代码随想录算法【Day2】
Day2
1.掌握滑动窗口法
2.模拟题,坚持循环不变量原则
209 长度最小的子数组
暴力法:
class Solution { public: int minSubArrayLen(int target, vector<int>& nums) { //暴力法 int i, j; //i代表起始点,j代表终止点 int sum; //子序列之和 int length = 0; //子序列的长度 int result = INT32_MAX; //最终结果 for(i = 0; i < nums.size(); i++){ sum = 0; for(j = i; j < nums.size(); j++){ sum += nums[j]; if (sum >= target){ length = j - i + 1; if(length < result) result = length; break; } } } return result == INT32_MAX ? 0 : result; } };
注意暴力法里面,如果找到符合条件的子序列了,直接break跳出j的循环
双指针法(滑动窗口法):
class Solution { public: int minSubArrayLen(int target, vector<int>& nums) { //双指针法 int i = 0, j = 0; //i代表起始点,j代表终止点 int sum = 0; //子序列之和 int length = 0; //子序列的长度 int result = INT32_MAX; //最终结果 for(j = 0; j < nums.size(); j++){ sum += nums[j]; while(sum >= target){ length = j - i + 1; if(length < result) result = length; sum -= nums[i]; i ++; } } return result == INT32_MAX ? 0 : result; } };
为什么时间复杂度是O(n)?
看每一个元素被访问的次数(这也是一个好的计算时间复杂度的方法),每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。
59.螺旋矩阵II
模拟题,难点在于边界值的判断,核心是坚持循环不变量原则,这里我们坚持左闭右开
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; //循环的圈数,若n为奇数,需特殊判断 int mid = n / 2; int count = 1; //矩阵赋值 int offset = 1; //每条要循环的边的长度 int i, j; while(loop--){ i = startx; j = starty; //按边依次循环,用到了4个for for( ; j < n - offset; j ++){ res[i][j] = count++; } for( ; 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 ++; } //若n为奇数,需要单独给中间值赋值 if(n % 2){ res[mid][mid] = count; } return res; } };