一:977. 有序数组的平方
思路: 双指针方法,因为暴力破解的思路很简单,就是先平方,然后排个序。所以这里使用的是双指针的方法。为什么会想到双指针呢。因为这个题是先比较,再排序。我认为就可以用双指针。
因为在两边一对比谁大,谁就去最后一个,然后尾指针减减或者首指针加加。因为双指针相等的条件就是一个数组的长度,也不会担心重复操作之类。
代码演示:
class Solution { public: vector<int> sortedSquares(vector<int>& A) { int k = A.size() - 1; vector<int> result(A.size(), 0); int first = 0; int last = A.size() - 1; for(int i = A.size()-1; i >= 0; i--){ if(A[first] * A[first] >= A[last]*A[last]){ result[i] = A[first] * A[first]; first++; }else{ result[i] = A[last]*A[last]; last --; } } return result; } };
二.209 长度最小的子数组
思路是:这道题的关键就是找子序列的起始位置,和子序列的结束位置。用暴力破解会超时,这里主要讲解滑动窗口的方法。说是滑动窗口实质上其实是双指针的用法。因为暴力破解是用两个循环来找起始位置和结束位置的是o(n^2)的算法。要o(n)的算法就只能用一个for循环来确定位置。就接是确定起始位置,还是结束位置呢。如果确定起始位置的话,就还是会走多次循环达不到优化的目的。而使用结束位置的话, 可以用for循环当作结束位置。就更好遍历。
方法是:for循环代表结束位置。 当sum>= target 时 记录长度 然后 使first 指针向前移动一位,达到滑动的目的
代码演示:
class Solution { public: int minSubArrayLen(int target, vector<int>& nums) { int sum = 0; int length; int first = 0; int result = INT32_MAX; for( int i = 0; i < nums.size(); i++){ sum+= nums[i]; while (sum >= target){ length = i -first + 1; result = result >length ? length : result; sum -=nums[first++]; } } return result == INT32_MAX? 0:result; } };
三.59.螺旋矩阵II
思路:确定左闭右开的原则;进行循环
代码演示:
class Solution { public: vector<vector<int>> generateMatrix(int n) { vector<vector<int>> res(n, vector<int>(n, 0)); int loop = n / 2; // 循环圈数 int startx = 0; int starty = 0;//起始位置 int count = 1; //记录每个格的值 int length = 1; //设定左闭右开的原则,需要减去的格子数 int mid = n/2; //螺旋矩阵 n 为奇数时 中间的格子循环不到需要另外讨论 int i = 0;//行数 int j = 0;//列数 while(loop--){ i = startx; j = starty; //给起始位置 for(;j < n - length ;j++){ res[i][j] = count++; } for(;i < n - length ; i++){ res[i][j] = count++; } for(;j > starty;j--){ res[i][j] = count++; } for(;i > startx; i--){ res[i][j] = count++; } startx++; starty++; length++; } if(n%2!=0){ res[mid][mid] = count; } return res; } };