滑动窗口
刚开始不太好想到滑动窗口这种方法,即使想到了也并没有办法证明滑动窗口方法的正确性,现在我也不会证明。只是会用,前几天做过一次,这是第二次做,记住了这个方法之后也是没有什么障碍。
例题
题目链接:209. 长度最小的子数组
题目描述:找出数组中满足其总和大于等于 target
的长度最小的子数组,并返回其长度。如果不存在符合条件的子数组,返回 0
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public: int minSubArrayLen(int target, vector<int>& nums) { int n=nums.size(); int sum=0,m=100010,j=0; for(int i=0;i<n;i++) { sum=sum+nums[i]; while(sum>=target){ m=min(m,i-j+1); sum-=nums[j++]; } } if(m==100010) return 0; return m; } };
|
相关题目
904. 水果成篮
题目描述:找一个最长连续子数组,满足子数组中至多有两种数字。返回子数组的长度。
这题题目描述很抽象,没看懂啥意思,去评论区的解释。
76. 最小覆盖子串
不会做,没思路,目前水平不够,直接跳。
矩阵规律
题目链接:59. 螺旋矩阵 II
题目描述:给定一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
例题
贪吃蛇输出
题目思路:直接按顺序输出,定义上下左右四个边界,从左到右输出上边界加一,从上到下输出右边界减一,从右向左输出下边界减一,从下到上输出左边界加一,依次输出就可以,因为上边界加一,从上到下就少输出一个,右边界减一,从右到左输出就少输出一个。从下向上输出时,下边界减一,上边界加一,正好按顺序输出,完美!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| class Solution { public: vector<vector<int>> generateMatrix(int n) { vector<vector<int>> res(n, vector<int>(n, 0)); int l=0,r=n-1,t=0,b=n-1,count=1; while(count<=(n*n)) { for(int i=l;i<=r;i++) { res[t][i]=count; count++; } t++; for(int j=t;j<=b;j++) { res[j][r]=count; count++; } r--; for(int j=r;j>=l;j--) { res[b][j]=count; count++; } b--; for(int j=b;j>=t;j--) { res[j][l]=count; count++; } l++; } return res; } };
|
循环不变量原则
思路:每条边按左闭右开的输出,每圈输出四次,每次输出边长减一个,这里直接贴一下代码随想录的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| class Solution { public: vector<vector<int>> generateMatrix(int n) { vector<vector<int>> res(n, vector<int>(n, 0)); int startx = 0, starty = 0; int loop = n / 2; int mid = n / 2; int count = 1; int offset = 1; int i,j; while (loop --) { i = startx; j = starty; for (j; j < n - offset; j++) res[i][j] = count++; for (i; i < n - offset; i++) res[i][j] = count++; for (; j > starty; j--) res[i][j] = count++; for (; i > startx; i--) res[i][j] = count++; startx++; starty++; offset += 1; } if (n % 2) res[mid][mid] = count; return res; } };
|
相关题目
54. 螺旋矩阵
进阶了一下,今天没时间了改天再做,这两天光建blog了。
LCR 146. 螺旋遍历二维数组
这题虽然是简单题,但是做起来比例题难,这题边界问题比较棘手。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { public: vector<int> spiralArray(vector<vector<int>>& array) { if (array.empty() || array[0].empty()) { return {}; } int t=0,l=0,r=array[0].size() -1,b=array.size()-1,n=array[0].size()*array.size(); vector<int> ans(n); int j=0; while(t <= b && l <= r){ for(int i=l;i<=r;i++) ans[j++]=array[t][i]; t++; for(int i=t;i<=b;i++) ans[j++]=array[i][r]; r--; if (t <= b) { for (int i = r; i >= l; i--) { ans[j++] = array[b][i]; } b--; } if (l <= r) { for (int i = b; i >= t; i--) { ans[j++] = array[i][l]; } l++; } } return ans; } };
|
前缀和
前缀和 在涉及计算区间和的问题时非常有用!
刚开始使用的暴力解法,一直不行,知道看了题解才知道,故意卡暴力解。然后自己也想不出什么好方法,就问的chatgpt,这种方法刚开始我还以为时间复杂度差不多呢。
例题
题目链接:区间和
题目描述:给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #include <cstdio>
int main() { int n; scanf("%d", &n); int a[n];
// 读取数组元素 for (int i = 0; i < n; i++) { scanf("%d", &a[i]); }
// 计算前缀和数组 int prefixSum[n + 1]; // prefixSum[0] = 0 prefixSum[0] = 0; for (int i = 1; i <= n; i++) { prefixSum[i] = prefixSum[i - 1] + a[i - 1]; }
// 处理区间查询 int l, r; while (scanf("%d %d", &l, &r) != EOF) { // 使用前缀和快速计算区间 [l, r] 的和 printf("%d\n", prefixSum[r + 1] - prefixSum[l]); }
return 0; }
|
相关题目
开发商购买土地
看起来挺难的,没看懂题目意思,明天再研究。