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


题目建议: 977题关键在于理解双指针思想 ,因为它的时间复杂度是o(n)。比暴力方法的o(nlogn)要好。
首先因为她是有序数组,正数平方后也是有序的,负数平方后可能大于正数平方。
```java
class Solution {
    public int[] sortedSquares(int[] nums) {
    //新建一个存排序后的数组
        int[] result=new int[nums.length];
        //右指针
        int right=nums.length-1;
        //左指针
        int left=0;
        //排序后的数组的初始索引
        int k=right;
        while(left<=right){
        //知道左右指针重合为止,左指针所指元素的平方和右指针所指元素的平方会一直比较大小,大的就放到新数组的右边。比如 [-4,-1,0,3,10]
        //一开始16小于100,所以新数组最右边存100,然后右指针往左移位(因为10平方已经确定是最大的了)
        //然后第二轮比较16大于9,所以新数组最右边倒数第二位存16,然后左指针往右移位
        //第三轮1和9比,第四轮1和0比较而且结束后左右指针重合了,循环结束。
            if (nums[left]*nums[left]>nums[right]*nums[right]){
                result[k]=nums[left]*nums[left];
                k=k-1;
                left++;
            }
            else{
                result[k]=nums[right]*nums[right];
                k=k-1;
                right--;
            }
        }
        return result;

    }
}

209.长度最小的子数组

题目建议: 本题关键在于理解滑动窗口,这个滑动窗口看文字讲解 还挺难理解的,建议大家先看视频讲解。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int numsize=nums.length;
        //开始指针start,结束指针end
        int start=0;
        int sum=0;
        int sublength=0;
        //result初始值是大于给定数据的长度,如果result到循环结束后都没有改变,说明不存在符合条件的子数组,返回0
        int result=numsize+1;
        int end;
        //[2,3,1,2,4,3]为例子。第一二三轮后sum=6,第四轮后sum=8大于7,然后就求子数组的长度是3-0+1=4,这是result是4,然后start指针右移,sum减去之前start指向的元素。
        //以此类推
        for(end=0;end<numsize;end++){
            sum+=nums[end];
            while(sum>=target){
                sublength=end-start+1;
                result=sublength<result?sublength:result;
                sum=sum-nums[start];
                start=start+1;

            }
        }
        //如果result到循环结束后都没有改变,说明不存在符合条件的子数组,返回0
        return result == numsize+1 ? 0 : result;
        
        


 
    }
}

59.螺旋矩阵II

题目建议: 本题关键还是在转圈的逻辑,在二分搜索中提到的区间定义,在这里又用上了。

class Solution {
    public int[][] generateMatrix(int n) {
        int startx=0;
        int starty=0;
        int count=1;//元素个数
        int offset=1;//统一的左闭右开
        int i,j;
        int[][] result =new int[n][n];
        //(i,j)是第i行第j列,n/2代表有几圈完整的;n/2代表完整的圈数
        //举例:
        // | 1  2  3  4|
        // | 12 13 14 5|
        // | 11 16 15 6|
        // | 10 9  8  7|
        int loop=0;

        while(loop<n/2){
            for (j=starty;j<n-offset;j++){
                result[startx][j]=count;
                count++;
            }//上面的循环结束后,j是3,count是3
            
             for (i=startx;i<n-offset;i++){
                result[i][j]=count;
                count++;
            }   //循环结束后,j是3,i是3,count是6
             for (;j>loop;j--){
                result[i][j]=count;
                count++;
            }   //循环结束后,j是0,i是3,count是9     
             for (;i>loop;i--){
                result[i][j]=count;
                count++;
            }   //循环结束后,j是0,i是0,count是12  
            loop++;   
            startx++;
            starty++;
            offset++;                
        }
        if (n%2==1){
            result[startx][starty]=n*n;
        }
        return result;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值