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

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

977.有序数组的平方

题目:977.有序数组的平方
文档讲解:代码随想录-977.有序数组的平方
视频讲解:哔哩哔哩-977.有序数组的平方
状态/时间:自己写没全部完成/二十分钟

思路:
定义一个左右指针,因为这是一个非递减数组,也可以从例子当中看出规律。
当左指针数组的平方大于右指针数组的平方时,直接丢到新数组里面就好,注意返回的也要是非递减数组,因此数组要从后往前赋值,即k-- (k为新数组的位置) 。最后要注意左边指针要++。
同理,当右指针数组的平方大于左指针数组的平方时,直接把右指针数组的平方丢到新数组里面,注意返回的也要是非递减数组,因此数组要从后往前赋值,即k–(k为新数组的位置) 。最后要注意右边指针要–。
最后把新数组返回就好了
代码:

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

注意:
别忘记左右边指针要++,新数组的指针要–。

209.长度最小的子数组

题目:209.长度最小的子数组
文档讲解:代码随想录-209.长度最小的子数组
视频讲解:哔哩哔哩-209.长度最小的子数组
状态/时间:没写出来/三十分钟

思路:
这道题可以用两个for暴力题解,已经滑动窗口解题。
这题用滑动窗口的思想就是:
定义左右指针,左指针不动,然后右指针++,同时进行累加,累加完判断会不会>=target,大于等于的话,(注意这里得是循环判断,为什么要循环,下面说了) 然后在判断原来的res跟right - left 谁小,小的赋值给res,左指针进行++,顺便也把左指针加入的数值从sum里面删除。
返回的时候我们要考虑一个这样的情况,就是假如nums就只有一个,所以返回判断一下res == Integer.MAX_VALUE,相等就返回0,不相等返回 res
代码:

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

注意:

这里的判断sum>=target 一定是个循环,不然如果左指针左边删掉第二个,sum也是>=target的情况就不会算在内了。
这里第一个循环可以用for,直接用right++在循环里面了,然后注意一下用for的话,判断最小用right - left + 1;

209.长度最小的子数组

题目:59.螺旋矩阵II
文档讲解:代码随想录-59.螺旋矩阵II
视频讲解:哔哩哔哩-59.螺旋矩阵II
状态/时间:只把前面两个用例做出来了/三十分钟

思路:
因为题目要求的是元素按顺时针顺序螺旋排列,这里我们可以用一个大的循环进行循环圈数,一圈一圈的进行输出。
在大循环里面,通过观察,可以发现通过四个循环可以进行输出。
每个小循环输出每行/列的第一个以及倒数第二个,那么这里就要设置好边界问题了。
还有循环的次数,可能是一圈,两圈,三圈等等。
最后发现,如果是单数圈的话,那么中间有一个元素就需要判断,然后再进行赋值了。

代码:

class Solution {
    public int[][] generateMatrix(int n) {
        // 循环次数
        int loop = 0;
        int i = 0, j = 0;
        int start = 0;
        int res[][] = new int[n][n];
        int count = 1;
        // 循环打印输出
        while (loop++ < n/2) {
            // 注意边界问题
            for (j = start; j < n - loop; j++) {
                res[start][j] = count++;
            }
            for (i = start; i < n - loop; i++) {
                res[i][j] = count++;
            }
            for (; j >= loop; j--) {
                res[i][j] = count++;
            }
            for (; i >= loop; i--) {
                res[i][j] = count++;
            }
            start++;
        }
        if (n % 2 == 1) {
            res[start][start] = count;
        }
        return res;
    }
}

注意:
这里要定义一个start,是因为循环的圈子不一样,赋值的地方也不一样。
还有就是要特别注意边界问题

反思:
第一次写的时候太粗细了,没考虑到其他圈数的情况,然后就只把两个用例写了出来。

  • 33
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值