代码随想录刷题-day2

113 阅读4分钟

977有序数组

题目具体位置

[977. 有序数组的平方](leetcode.cn/problems/sq…)

方法一:暴力求解

  1. 直接对nums数组中每个数求平方;

  2. 调用库函数进行排序

方法一具体代码

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

}

方法二:双指针法

方法二具体代码

class Solution {
    public int[] sortedSquares(int[] nums) {
        int len=nums.length;
        //将所有的元素取平方
        for(int i=0;i<len;i++){
            nums[i]=nums[i]*nums[i];
        }
        int[] result=new int[len];
        //定义双指针left right
        int left=0;
        int right=len-1;
        //currentIndex代表result数组中的下标;最开始指向最后
        int currentIndex=len-1;
        //不断循环,每次将left 或 right 指向的元素较大者传给result[currentIndex]
        while(left<=right){
            if(nums[left]<=nums[right]){
                result[currentIndex]=nums[right];
                right--;
            }
            else{
                result[currentIndex]=nums[left];
                left++;
            }
            currentIndex--;

        }
        return result;
    }
}

209.长度最小的子数组

题目具体位置

[209. 长度最小的子数组](leetcode.cn/problems/mi…)

方法一:暴力解法

通过暴力遍历所有可能的情况,以此来取最小的长度。(当然超时了)

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int len=nums.length;
        int minLength=len+1;
        int sum=0;
        //i代表起始位置
        for(int i=0;i<len;i++){
            sum=0;
            //j代表终止位置
            for(int j=i;j<len;j++){
                sum+=nums[j];
                if(sum>=target){
                    minLength=minLength<(j-i+1)?minLength:(j-i+1);
                    //一旦找到了就可以break;因为在暴力这个方法里面,一旦找到了一定是当前轮次最小的范围了
                    break;
                }
            }
        }
        return minLength=(minLength==len+1)?0:minLength;
    }
}

方法二:滑动窗口法

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int len=nums.length;
        int sum=0;
        int left=0;int right=0;
        //输出的最大值也只可能是len,这里初始化为len+1也无伤大雅
        int minLength=len+1;
        for(right=0;right<len;right++){
            sum+=nums[right];
            //这里正如carl哥举的那个例子 1、1、1、1、100 target=100
            //left是需要循环往前移的,直到小于target
            while(sum>=target){
                minLength=minLength<(right-left+1)?minLength:(right-left+1);
                sum-=nums[left];
                left++;
            }
        }
        return minLength<len+1?minLength:0;
    }
}

自留问题:

原来的错误、未写完的代码如下(用于个人警醒)

  • 这里原来编写的时候就很别扭,需要考虑很多情况。
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int len=nums.length;
        int sum=0;
        int left=0;int right=0;
        sum+=nums[right];
        //输出的最大值也只可能是len,这里初始化为len+1也无伤大雅
        int minLength=len+1;
        while(right<len){
            //求当前left~right这一段滑动窗口的和
            if(sum>=target){
                minLength=minLength<(right-left)?minLength:(right-left);
                sum-=nums[left];
                left++;
            }
            if(sum<target){
                sum+=nums[right];
                right++;
            }
        }
        return minLength<len+1?minLength:0;
    }
}

59 螺旋矩阵 II

59. 螺旋矩阵 II

59 螺旋矩阵 II

59. 螺旋矩阵 II

解题思路:

  • 题目中是顺时针输出矩阵,所以在进行纸上模拟的时候,也要跟着他的思路,看是否能够顺时针输出

    • 一开始想的是直接顺序输出,然后通过某种方法后续调整成顺时针,但是无法实现
  • 循环不变很重要,所谓循环不变就是每一轮循环逻辑上都应该是相同的

  • 我个人所写的代码,经过推算,loop的取值是可以和每一次的“碰壁”相结合的,所以不用额外设置一个变量——类似于wall之类的来调整。

QQ图片20240126112506.jpg

具体代码如下:

class Solution {
    public int[][] generateMatrix(int n) {
        int[][]result=new int [n][n];
        int loop=1;
        int start=0;//因为是n阶矩阵,所以每轮循环更新起始点就是[start,start]
        //变量i表示行,变量j表示列
        int i,j;
        //变量num代表数字,插入数字,然后每次加1
        int num=1;
        while(loop<=n/2){
            //模拟① 最上面的从左往右
            for(j=start;j<n-loop;j++){
                result[start][j]=num;
                num++;
            }
            //模拟② 最右边的从上往下
            //此时j已经有值了,不需要去动他
            for(i=start;i<n-loop;i++){
                result[i][j]=num;
                num++;
            }
            //模拟③ 最下面的从右往左
            //此时i已经有值了,不需要去动他
            for(;j>start;j--){
                result[i][j]=num;
                num++;
            }
            //模拟④ 最左边的从下往上
            for(;i>start;i--){
                result[i][j]=num;
                num++;
            }
            loop++;
            start++;
        }
        if(n%2!=0){
            result[n/2][n/2]=n*n;
        }
        return result;
        
    }
}