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

链接:代码随想录

文章目录 


解题思路

1.977.有序数组的平方 解题思路

非递减数列的意思就等价于递增数列,最容易想到的是全部平方再排序,而这里可以采用更为迅速的双指针法进行求解,即满足数组左右同时进行,平方和排序同时进行则大幅减小时间复杂度

代码如下(示例):

class Solution {
    public int[] sortedSquares(int[] nums) {
        int left = 0;
        int right = nums.length-1;
        int[] num = new int[nums.length];//定义数组存放平方后排序好的数字
        int index = nums.length-1;
        while(left <= right){
            if(nums[right] * nums[right] > nums[left] * nums[left]){
                num[index--] = nums[right]*nums[right];//存放左右较大的一个,倒着放
                --right;
            }else{
                num[index--] = nums[left]*nums[left];
                ++left;
            }
        }
        return num;
    }
}

2.209.长度最小的子数组 解题思路

首先是暴力解法,从每一个数开始找到各个满足条件的数列,最后返回最小值;滑动窗口的解法则类似双指针,一个满足条件的数组的前侧后侧各一个指针,并且前指针一旦满足关系,后指针则需向前挪移,按着这个逻辑,找到长度最小的子数组,时间复杂度为O(N)。

代码如下(示例):

 

//暴力解法
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int sum = 0;
        int result = Integer.MAX_VALUE;//取最大值
        int subLength = 0;
        for(int i = 0;i < nums.length;i++){
            sum = 0;//每次循环数组和归零
            for(int j = i;j < nums.length;j++){
                sum+=nums[j];
                 if (sum >= target) { 
                    subLength = j - i + 1; //若?前的式子为TRUE,则result为:前的值
                    result = result < subLength ? result : subLength;//反之则取:后的值
                    break; //找到最小值即退出循环
                }
            }
        }
        return result == Integer.MAX_VALUE? 0 : result;//判断是否取值
    }

//滑动窗口
   public int minSubArrayLen(int s, int[] nums) {
        int left = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            while (sum >= s) {
                result = Math.min(result, right - left + 1);//判断最小符合条件的数组
                sum -= nums[left++];//后侧指针向前移动
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }

}



3.59.螺旋矩阵|| 解题思路

分别表示每一圈上下左右的循环,然后一圈一圈的往里面绕,最后单独处理中间的值

代码如下(示例):

class Solution {
    public int[][] generateMatrix(int n) {
        int loop = 0;
        int[][] res = new int[n][n];
        int start = 0;
        int count = 1;
        int i,j;
        //顺时针方向
        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;
    }
}

 


总结

双指针法是特别常用的方法,除了977.的方法相向左右指针,还有209.所用到的滑动窗口,需要理解并记忆才好独自敲出代码,最后的59.则更多地是去分析理解这个过程,无法理解过程连暴力算法都没法开头,但总的来说熟能生巧,一题可巧解多题,仍需努力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kingsman、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值