算法刷题Day2 - 数组Part2|LC209. Minimum Size Subarray 最小长度子数组|LC59. Spiral Mareix II 螺旋矩阵 II|

今天这两题是数组中的Medium题,比起昨天的基础的数组增删改查操作的题目稍复杂。

LeetCode - 209. Minimum Size Subarray 最小长度子数组

解题目标:给定一个数组以及target,求出最短的并且总和大于等于target的子数组的长度。

想要获取一个最短的子数组的长度,也就是找出数组中某两个位置的index。本题主要采用了滑动窗口的思路,设置start和end两个指针表示头尾来截取目标子数组,end指针在前面探路,start指针根据当前总和是否超出target再决定是否向前移动,最终的结果也就是end - start + 1。本题的目标只是求最小长度,我们只要在循环中保持记录当前最小值就可以了,而不是打印出最终的子数组,因此不用过多思考最后start和end最后应该停留在什么位置。

滑动窗口其实和双指针的思想是类似的,我们使用双指针也就是为了能一次循环遍历之后直接找出答案,滑动窗口中的终止位置应该是跟着for循环正常走的,其精髓其实在于如何移动起始位置的逻辑。在我第一次写这题的时候犯了一个错误,中间更新start时判断写的是if,这样就会导致减去start的值有可能依然还是大于target,导致了一些情况没有被记录。在滑动窗口中因为不应该是一次性的判断,而是专注于在每一次循环中继续不断查找可能的解,因此这里需要用while循环持续地进行减start的操作直到小与target。

import static java.lang.Integer.MAX_VALUE;
import java.lang.Math;

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int start = 0;
        int sum = 0;
        Integer min_length = MAX_VALUE;
        for (int end = 0; end < nums.length; end++) {
            sum += nums[end];
            while (sum >= target) {
                min_length = Math.min(min_length, end - start + 1);
                sum -= nums[start];
                start++;
            } // 持续移动start位置,更新滑动窗口大小
        }
        return min_length == MAX_VALUE ? 0 : min_length;
    }
}

LeetCode - 59. Spiral Matrix II

解题目标:给定一个整数n,生成一个1~n^2的一个n*n正方形螺旋矩阵。

这题其实没有什么特别复杂的逻辑,重点在于如何在二维数组里转圈更新数字,以及特殊的边界条件处理。这里使用的边界处理是左闭右开的思路,一条边的最后一个元素留给下一条边来处理,每一次循环嵌套四个不同边的更新逻辑处理一圈。同时需要关注给定的矩阵需要转几圈(n / 2 圈),每个边的起始位置,以及当前所遍历的边长sideLen(n - currLayer - 1)。注意特殊情况,如果n为奇数,那么中心点的位置应该要单独更新。 

class Solution {
    public int[][] generateMatrix(int n) {
        int num = 1;
        int layer_num = n / 2;
        int [][] res = new int[n][n];
        for (int currLayer = 0; currLayer < layer_num; currLayer++) {
            int sideLen = n - currLayer - 1; //当前需遍历的长度(边长-1)
            //上
            for (int a = currLayer; a < sideLen; a++) {
                res[currLayer][a] = num;
                num++;
            }
            //右
            for (int b = currLayer; b < sideLen; b++) {
                res[b][sideLen] = num;
                num++;
            }
            //下
            for (int c = sideLen; c > currLayer; c--) {
                res[sideLen][c] = num;
                num++;
            }
            //左
            for (int d = sideLen; d > currLayer; d--) {
                res[d][currLayer] = num;
                num++;
            }
        }
        //center
        if (n % 2 != 0) {
            res[n / 2][n / 2] = num;
        }
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值