有序数组的平方
link:977. 有序数组的平方 - 力扣(LeetCode)
非递减顺序
一个数列中的元素从左到右依次不减,或者说不降序排列.
比如:1233445,12345.
思路分析
如果看到数组能条件反射到双指针那已经是win了.
根据题意平方之后的数一定在数组的两端.两个指针一首一尾,从后往前更新数组.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public int[] sortedSquares(int[] nums) { int left = 0; int right = nums.length - 1; int[] result = new int[nums.length]; int index = result.length - 1 ; while(left <= right) { if(nums[left]*nums[left] > nums[right]*nums[right]) { result[index--] = nums[left] * nums[left++]; }else{ result[index--] = nums[right] * nums[right--]; } } return result; } }
|
长度最小的子数组
link:209. 长度最小的子数组 - 力扣(LeetCode)
双指针变形——滑动窗口
其实也可以理解成给入队的队列一个给定的大小变成窗口,先入队元素,然后和target进行比较,大于等于target就出队先进的元素,再进新元素并且标记好原来大于等于target的数组长度.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Solution { public int minSubArrayLen(int target, int[] nums) { int begin = 0; int sum = 0; int result = Integer.MAX_VALUE; for(int end = 0; end < nums.length;end++) { sum += nums[end]; while(sum >= target) { result = Math.min(result, end - begin + 1); sum -= nums[begin++]; } } return result == Integer.MAX_VALUE ? 0 : result; } }
|
关键点:如何移动起始位置
如果循环中的标记位在起始位置,起始位置和终止位置都需要移动一遍和暴力解法无差别,所以我们的标记位一定是终止位.
螺旋矩阵 II
link:59. 螺旋矩阵 II - 力扣(LeetCode)
奇怪的代码掌控力… 主要问题在边界处理
顺序解决
按照本来的逻辑
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
| class Solution { public int[][] generateMatrix(int n) { int l = 0,r = n - 1,t = 0,b = n-1; int[][] result = new int[n][n]; int num = 1; int tar = n * n; while(num <= tar) { for(int i = l;i <= r;i++){ result[t][i] = num++; } t++; for(int i = t; i <= b; i++){ result[i][r] = num++; } r--; for(int i = r; i >=l; i--){ result[b][i] = num++; } b--; for(int i = b;i >= t;i--) { result[i][l] = num++; } l++; } return result; } }
|
改编版本
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 36 37 38 39
| class Solution { public int[][] generateMatrix(int n) { int loop = 0; int[][] res = new int[n][n]; int start = 0; int count = 1; int i, j;
while (loop++ < n / 2) { for (j = start; j < n - loop; j++) { res[start][j] = count++; }
for (i = start; i < n - loop; i++) { res[i][j] = count++; }
for (; j >= loop; j--) { res[i][j] = count++; }
for (; i >= loop; i--) { res[i][j] = count++; } start++; }
if (n % 2 == 1) { res[start][start] = count; }
return res; } }
|
Tips
1.遇到有序数组考虑二分法.
2.双指针(找准循环不变量中的不变量).
3.求连续子数组的总和可用滑动窗口解决.