代码随想录训练营第二天 | 977、有序数组的平方 209、长度最小的子数组 59、螺旋矩阵II

977、有序数组的平方

最初我想到的为暴力解法     时间复杂度为 O(nlogn)

(直接遍历每一个数组元素使其平方,然后进行排序)

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

双指针解法                        时间复杂度为 O(n)

接下来在视频提示下,指导可以使用双指针(由于是含负数的有序数组 =》由数组中间的元素朝两边的元素平方是依次增大的 =》 创建 left ,right 指针利用归并思想将其存入新的数组(用空间换时间))

class Solution {
    public int[] sortedSquares(int[] nums) {
        int n = nums.length;
        int left = 0;
        int right = n - 1;
        int[] res = new int[n];
        while(left <= right){
            int Lsq = nums[left] * nums[left];
            int Rsq = nums[right] * nums[right];
            if(n > 0){
                if(Lsq <= Rsq){
                    res[n - 1] = Rsq;
                    right--; 
                    n--;
                }else{
                    res[n - 1] = Lsq;
                    left++;
                    n--;
                }
            }    
        }
        return res;
    }
}

209、长度最小的子数组

看见 连续子数组 首先就想到了滑动窗口思想

自己根据理解的滑动窗口思想写了一个题解

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0;
        int right = 0;
        int res = Integer.MAX_VALUE;
        int len = 0;
        int sum = 0;
        while(right < nums.length){
            while(right < nums.length && sum < target){
                sum += nums[right++];
                len++;
            }
            System.out.println(sum);
            if(right == nums.length && sum < target && res == Integer.MAX_VALUE){
                return 0;
            }
            res = Math.min(len,res);

            while(sum >= target){
                res = Math.min(len,res);
                sum -= nums[left++];
                len--;
            }
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }
}

但是时间复杂度很高 O(n^2) 最坏的情况下需要遍历两次,有点重复冗杂

 观察代码后发现:

在第二个while循环中,当子数组的总和已经大于等于目标值时,将左指针向右移动并更新子数组长度,然后再次判断总和是否大于等于目标值,这会导致在右指针不断向右移动的过程中,重复计算子数组的长度。

例:

例如,当nums数组为[2,3,1,2,4,3],target为7时,第一个子数组为[2,3,1,2],长度为4,当右指针移动到4时,子数组变为[4,3],长度变为2,但是在执行第二个while循环时,左指针向右移动,子数组变为[3],长度变为1,然后再次判断总和是否大于等于目标值,重复计算子数组的长度。

修改后:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0;
        int right = 0;
        int sum = 0;
        int res = Integer.MAX_VALUE;
        int len = 0;
        while (right < nums.length) {
            sum += nums[right];
            len++;
            while (sum >= target) {
                res = Math.min(res, len);
                sum -= nums[left];
                left++;
                len--;
            }
            right++;
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }
}

 

59、螺旋矩阵II

看见该题目时,第一想法就是模拟,大脑先跟着题目要求走,找到构成螺旋数组的一些限制条件代码便如下:

class Solution {
    public int[][] generateMatrix(int n) {
    int[][] matrix = new int[n][n]; // 创建一个 n × n 的矩阵
    int num = 1; // 要填充的数字,初始值为 1
    int rowStart = 0, rowEnd = n - 1; // 当前填充区域的上下边界
    int colStart = 0, colEnd = n - 1; // 当前填充区域的左右边界
    while (rowStart <= rowEnd && colStart <= colEnd) { // 当还有未填充的区域时继续循环
        // 填充上行
        for (int j = colStart; j <= colEnd; j++) {
            matrix[rowStart][j] = num++; // 将当前数字填充到矩阵中,并将 num 加一
        }
        rowStart++; // 上边界下移一行
        // 填充右列
        for (int i = rowStart; i <= rowEnd; i++) {
            matrix[i][colEnd] = num++; // 将当前数字填充到矩阵中,并将 num 加一
        }
        colEnd--; // 右边界左移一列
        // 填充下行
        if (rowStart <= rowEnd) { // 如果当前上下边界仍然有交叉区域
            for (int j = colEnd; j >= colStart; j--) {
                matrix[rowEnd][j] = num++; // 将当前数字填充到矩阵中,并将 num 加一
            }
            rowEnd--; // 下边界上移一行
        }
        // 填充左列
        if (colStart <= colEnd) { // 如果当前左右边界仍然有交叉区域
            for (int i = rowEnd; i >= rowStart; i--) {
                matrix[i][colStart] = num++; // 将当前数字填充到矩阵中,并将 num 加一
            }
            colStart++; // 左边界右移一列
        }
    }
    return matrix; // 返回填充好的矩阵
}  
}

该题目解决后的思考:需要关注一些不变量来寻找规律,并利用它们来进行题目解决过程中的一些限制

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值