算法训练营第二天/977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

977.有序数组的平方

977. 有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

 主要思路:双指针

因为nums是从小到大排序的,可能包含负数,最小负数和最大正数的平方都有可能是平方后新数组的最大值,所以我们要左右向内比较大小(快排),谁大就把谁放在新数组最末尾,所以需要逆序放入。  

因为i=j时也有一个元素,我们不能落掉这个元素不管,所以要写i<=j而不是i<j。

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

    }
}

209.长度最小的子数组

209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组[numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

主要思路:滑动窗口

循环移动end指针,每次都计算窗口数的和,大于的时候就记录窗口长度看看是不是更小了,把小的记录给结果,然后sum减去起始指针的值,起始指针++;

最后记得要判断是否start==0,即整个数组加起来的和都小于target 如果是就返回0

注意result要初始化为最大值Integer.MAX_VALUE这样才能比较出谁小

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length;
        int start = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        for(int end = 0;end >=start && end < n;end++){
            sum += nums[end];
            while(sum >= target){
                int len = end-start+1;
                result = (result < len )? result : len;  //或者result = Math.min()            
                sum -= nums[start];
                start ++;
            }
        }

        return (start == 0) ? 0 : result;
    }
}

 59.螺旋矩阵II

59. 螺旋矩阵 II

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

思路:在圈数限制内循环遍历每条边,遍历行,列放入二维数组对应行,列

注意边界条件

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] res = new int[n][n];
        //转圈:先看行,再看列 最后一个格子让给下一条边
        int startx = 0; 
        int starty = 0; //起始位置
        int offset = 1;//限制边界点条件
        int cnt = 1;//每有一个数字就计数一次,最后得到n的值
        int loop = 1;//记录圈数
        int i,j;// j 代表列, i 代表行;
        //总共转n/2圈 如果n是偶数
        while(loop <= n/2){
            //j代表不同列 i代表不同行
            for(j=starty; j<n-offset ; j++){//上边
                res[startx][j] = cnt++ ;
            }
            for(i=startx; i<n-offset ; i++){//右边
                res[i][n-offset] = cnt ++ ;//或res[i][j] = cnt++;
            }
            for( ; j > starty ; j--){//下边
               res[n-offset][j] = cnt++; //或res[i][j] = cnt++;
            }
            for( ; i>startx ; i--){
                res[i][starty] = cnt++;//或res[i][j]= cnt++;
            }

            //进入内圈
            startx++;
            starty++;
            offset++;
            loop++;

        }
        //此时startx和stary已经走完了圈,到了最中间的位子(如果n是奇数的话)
        //如果n是奇数 再单独数组中间赋n的值
        if(n % 2 == 1 ){
            res[startx][starty] = cnt;
        }
        return res;
    }
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值