977 有序数组的平方
暴力法:一个for循环把所有元素进行平方计算,再对这个数组进行排序。
双指针法:因为最大的元素一定是从两边开始的,所以设置头指针在最左边,尾指针在最右边,依次进行平方的比较,较大的一方从后往前放入数组即可。
public int[] sortedSquares(int[] nums) {
int length = nums.length;
int[] result = new int[length];
int k = length-1;
for (int i=0,j=length-1;i<=j;){
if (nums[i]*nums[i] < nums[j]*nums[j]){
result[k--] = nums[j]*nums[j];
j--;
}else {
result[k--] = nums[i]*nums[i];
i++;
}
}
return result;
}
209 长度最小的子数组
暴力法:用两层for循环,遍历所有可能的子数组,找出长度最小的。
滑动窗口:滑动窗口思想实质上也是双指针的体现,只不过我们比较的是两个指针的区间,像是一个“窗口”。
这道题设置一个起始指针和一个终止指针,用终止指针来遍历数组,每次遍历都比较区间值与target值,如果满足区间值大于等于target值,就比较长度min,取较小值。
public int minSubArrayLen(int target, int[] nums) {
int min = Integer.MAX_VALUE;
int i = 0;
int sum = 0;
for (int j = 0; j < nums.length; j++) {
sum += nums[j];
while (sum >= target){
min = Math.min(min, j-i+1);
sum -= nums[i];
i++;
}
}
return min == Integer.MAX_VALUE ? 0 : min;
}
59 螺旋矩阵
思路:跟二分查找有一个共同点,就是得遵循循环不变量原则。循环指的是每一次循环一圈,不变量指的是插入元素的规则不变,比如左闭右开,就得一直坚持左闭右开,不能途中换成其他规则。
这道题在每一次循环(也就是每一圈),分别上侧从左到右、右侧从上到下、下侧从右到左、左侧从下到上插入元素即可。
public int[][] generateMatrix(int n) {
int x = 0, y = 0;
int offset = 1;
int loop = 0;
int count = 1;
int[][] result = new int[n][n];
while (loop++ < n/2){
for (; y < n-offset; y++){
result[x][y] = count++;
}
for (; x < n-offset; x++){
result[x][y] = count++;
}
for (; y >= offset; y--){
result[x][y] = count++;
}
for (; x >= offset; x--){
result[x][y] = count++;
}
offset++;
x++;
y++;
}
if (n%2==1){
result[x][y] = count;
}
return result;
}
数组篇总结
两天的数组学习,了解了数组的一些特性和基本的一些解题方法。
一般暴力法都是两层for循环根据题意解决。
- 二分法,主要注意遵循循环不变量原则
- 双指针法,通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
- 滑动窗口:滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)的暴力解法降为O(n)。
- 模拟行为:主要注意遵循循环不变量原则