977.有序数组的平方|209.长度最小的子数组|59.螺旋矩阵||【算法学习笔记】

691 阅读2分钟

977.有序数组的平方|209.长度最小的子数组|59.螺旋矩阵||【算法学习笔记】

  1. 有序数组的平方 要求对一个递增序列,也按递增的方式返回每个数字的平方在一个数组里

第一种解法是 暴力解法 ,即先用一个for循环得到每个数字的平方,再用sort()方法对它们进行排序。

class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] ans = new int[nums.length];
        for (int i = 0; i < nums.length; ++i) {
            ans[i] = nums[i] * nums[i];
        }
        Arrays.sort(ans);
        return ans;
    }
}

第二种解法是 双指针解法 ,要理解的是题目给的数组,数组的两端平方完后一定是数组的最大值,所以可以使用双指针从两端开始遍历,然后新建一个数组,从数组的尾部开始填入数据。要注意的是不要忽略left=right这种情况。

class Solution 
    public int[] sortedSquares(int[] nums) {
        int left=0;
        int right=nums.length-1;  //定义右指针
        int index=nums.length-1;  //定义要填入数据的位置
        int[] result=new int[nums.length];
        while (left <= right) {   //左右指针比较,较大元素放入新数组右边,然后左指针向右
            if (nums[left] * nums[left] > nums[right] * nums[right]) {  
                result[index--] = nums[left] * nums[left];
                left++;
            }
            else {                //右指针向左
                result[index--] = nums[right] * nums[right];
                right--;
            }
        }
    return result;                             
    }
}
  1. 长度最小的子数组 这道题的要求是在nums这个数组找到大于等于target的连续子数组,最后返回它的长度

第一种解法是 暴力解法 ,即用两个for循环查找数组,但是O(n^2)的时间复杂度在这道题时间超时了,此方法不适用。

第二种解法是 滑动窗口解法,即用一个for循环来完成查找。需要注意的第一点是这个for循环的指针应该指向终止位置,如果指向起始位置,那么还是和暴力解法一样,第二个指针还要遍历一遍数组。第二点是当要区分while和if条件,当sum满足题目条件后,还需让起始位置的指针继续向前移动,这样就形成了滑动窗口。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int sum = 0; //定义sum求数组和
        int i = 0;   //i定义起始位置的指针
        int result = Integer.MAX_VALUE;  //先把结果定义为一个最大值
        for(int j = 0;j <= nums.length - 1; j++) {   //j定义终止指针指向的位置,即用来求sum
            sum += nums[j];
            while(sum >= target) {       //当满足条件后,i++寻找更优解
                result = Math.min(result,j-i+1);   //用min()更新结果
                sum = sum - nums[i];
                i++;
            }
           
        }
    return result== Integer.MAX_VALUE?0:result;    //当result没有更新,即找不到目标子数组,返回0
    }
}
  1. 螺旋矩阵II 这道题的要求是在通过给的n形成一个顺时针并且递增的正方形矩阵

在做这道题的时候,要注意的第一点是要遵循循环不变量原则,即每次遍历都要按照一定的规则遍历,比如这道题我用的是左闭右开的写法。其它我写在注释里。

class Solution {
    public int[][] generateMatrix(int n) {
    int[][] res=new int[n][n];
    int loop=n/2;  //控制循坏次数
    int startx=0;  //每次循环的开始点
    int starty=0;  //
    int count=1;   //定义填充数字
    int offset=1;  //定义偏移量来控制循环结束位置
    int i=0;
    int j=0;
    while(loop-- >=0){
        i = startx;
        j = starty;
        for(j=starty;j<n-offset;j++){
            res[startx][j] = count++;
        }
        for(i=startx;i<n-offset;i++){   //注意这里j已经遍历到起始位置
            res[i][j]=count++;
        }
        for(;j>starty;j--){             //i已经遍历到起始位置
            res[i][j]=count++;
        }
        for(;i>starty;i--){             
            res[i][j]=count++;
        }
        startx++; //下次循环从内圈开始
        starty++;
        offset++; //偏移量加一


    }
    if(n%2==1){
        res[i][j]=count;    //如果n为奇数,用来填充最后一个数
    }
    return res;
    }
}