文档详解:代码随想录
状态:除了第一题,后两题自己做的时候无法想到最优解。
leecode 977 有序数组的平方
思路:
这道题的思路主要是在这个非递减递减顺序排序的数组中,负数的平方值是递减的,而非负数的平方值是递增的,所以平方的大小从两端往中间是递减的。由此可以看出用相向的双指针一个指向数组头部一个指向数组尾部。对比两个指针的平方值或者绝对值,将大的值移入新的数组尾部记录,然后将指针向中间移动一位,直到两个指针见面。
代码实现:
public static int[] sortedSquar(int[] nums) {
int[] results=new int[nums.length];
int left=0;
int right=nums.length-1;
int i=nums.length-1;
while(left<=right){
int absL = Math.abs(nums[left]);
int absR = Math.abs(nums[right]);
if(absL<absR){
results[i--]=absR*absR;
right--;
}else {
results[i--]=absL*absL;
left++;
}
}
return results;
}
leecode 209 长度最小的子数组
思路:
这题暴力解法很容易想到,对数组的每个元素都往后全部遍历,然后找到最小值。
所以这道题的关键是用滑动窗口。这个是双指针的一种,但是要理解循环内部 “i” 指向的其实是窗口终点不是起点。如果是起点的话,那和暴力解法的思路就一样的了,那算法复杂度还是On^2,并没有被优化。这个i作为窗口终点往后移动,当满足大于目标值的集合时才停下,然后慢慢移动前面的指标来缩小窗口,找到当前终点位置的最小窗口,然后再重新往后移动直到终点位置到达数组尾部。
代码:
public static int minSubArrayLen(int target, int[] nums) {
int sum=0;
int subLen=0;
int result= Integer.MAX_VALUE;
int i=0;
for(int j=0;j<nums.length;j++){
sum+=nums[j];
while(sum>=target){
subLen=j-i+1;
result=Math.min(subLen,result);
sum-=nums[i++];
}
}
return result==Integer.MAX_VALUE?0:result;
}
leecode 59 螺旋矩阵
思路:
这道题主要是找到循环不变量,每一条边的规则都要是一样的,遵循左闭右开或者左闭右闭。其实画图把过程写清楚,把四个点的坐标写出来仔细体会一下过程就很好理解。
左闭右开:
这种方法要注意,得用循环的轮数来作为最外层的循环判断条件。因为当n为奇数的时候,因为右开的原则,如果直接用count<n^2来判断,在最后一轮,剩下的一格会处于四条边的开规则里面。所以进入不了任意一条边的for循环,那么count就不会再增长,从而进入死循环。所以写左闭右开的时候,要用旋转了多少轮来控制次数,在最后也要判断一下是否为奇数从而填充最后一格数据。次数为n/2。但是这种写法只需要用两个变量ij来记录,因为左闭右开四个点的坐标的变化是同步的(画图可以直观的体会到)。
代码:两种,下面一种是一开始自己做的比较呆
//循环不变量是规则 左闭右开
private static int[][] generateMatrixFir(int n) {
int[][] result = new int[n][n];
int startRotateX = 0;
int i, j;
int count = 1;
for (int k = 1; k <= n / 2; k++) {
for (j = startRotateX; j < n - k; j++) {
result[startRotateX][j] = count++;
}
for (i = startRotateX; i < n - k; i++) {
result[i][j] = count++;
}
for (; j >= k; j--) {
result[i][j] = count++;
}
for (; i >= k; i--) {
result[i][j] = count++;
}
startRotateX++;
}
if (n % 2 == 1) {
result[startRotateX][startRotateX] = count;
}
return result;
}
//自实现,左闭右开
private static int[][] generateMatrixSec(int n) {
int[][] result = new int[n][n];
int a = 0, c = n - 1;
int count = 1;
int loop = 1;
while (loop++ <= n / 2) {
for (int i = a; i < c; i++) {
result[a][i] = count++;
}
for (int i = a; i < c; i++) {
result[i][c] = count++;
}
for (int i = c; i > a; i--) {
result[c][i] = count++;
}
for (int i = c; i > a; i--) {
result[i][a] = count++;
}
a++;
c--;
}
if (n % 2 == 1) {
result[a][a] = count;
}
return result;
左闭右闭:
//自实现,左闭右合
private static int[][] generateMatrixThir(int n) {
int[][] result = new int[n][n];
int a = 0,b=0, c = n - 1,d=n-1;
int count=1;
while(count<=n*n){
for (int i = a; i <=c ; i++) {result[a][i]=count++;}
a++;
for (int i = a; i <=c ; i++) {result[i][c]=count++;}
c--;
for (int i = c; i >=b ; i--) {result[d][i]=count++;}
d--;
for (int i =d ; i >=a ; i--) {result[i][b]=count++;}
b++;
}
return result;
}