数组刷题 977. 有序数组的平方 | 209. 长度最小的子数组 | 59. 螺旋矩阵 II |54.螺旋矩阵

977. 有序数组的平方

  • 双指针,首先要明确一点,有序的数组,平方后,最大值只能是在左右
  • 只需要在数组的左右放置两个指针,向中间移动,设置好循环停止条件
class Solution {
    public int[] sortedSquares(int[] nums) {
        //双指针
        //平方后,最大值只可能是在两端
        int[] sqrNums = new int [nums.length]; 
        int left = 0,right=nums.length-1,index = nums.length - 1;
        while(left <= right){
            int l = nums[left] * nums[left];
            int r = nums[right] * nums[right];
            if(l > r){
                sqrNums[index] = l;
                left ++;
            }else{
                sqrNums[index] = r;
                right --;
            }
            index --;
        }
        return sqrNums;
    }
}

###209. 长度最小的子数组

  • 滑动窗口,也是双指针的一种,也可以使用deque
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //双向队列用做滑动窗口
        Deque<Integer> deque = new ArrayDeque<>();
        //计算和
        int sum = 0;
        //计算子数组最小长度
        int cnt = Integer.MAX_VALUE;
        for(int i = 0; i < nums.length; i++){
            deque.offerLast(nums[i]);
            sum += nums[i];
            while(sum >= target){
                cnt = Math.min(cnt,deque.size());
                sum -= deque.pollFirst();
                
            }
        }
        return cnt == Integer.MAX_VALUE? 0: cnt;
    }
}

双指针做法

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //双指针
        int sum =0;
        int cnt = Integer.MAX_VALUE;
        int fast = 0,slow = 0;
        for(;fast< nums.length;fast ++){
            sum += nums[fast];
            while(sum >= target){
                cnt = Math.min(cnt,fast - slow + 1);
                sum -= nums[slow];
                slow ++;
            }
        }
        return cnt == Integer.MAX_VALUE? 0: cnt;
    }
}

###59. 螺旋矩阵 II

  • 螺旋矩阵也需要考虑 左右区间 左闭右开还是 左闭右闭

**要考虑 |偏移量| 循环次数| 每次循环开始的节点|矩阵的边是否时奇数 **

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] matrix = new int[n][n];
        
        int mid = n / 2;
        int loop = n / 2;
        int x = 0,y=0;
        int offset = 1;
        int count = 1;
        int i,j ;
        while(loop > 0){
            i = y;
            j = x;
            for(; j < n - offset; j ++){
                matrix[i][j] = count++;
            }
            for(;i < n - offset; i++){
                matrix[i][j] = count++;
            }
            for(;j >= offset ; j--){
                matrix[i][j] = count++;
            }
            for(;i >= offset; i--){
                matrix[i][j] = count++;
            }
            offset ++;
            x++;
            y++;
            loop --;
        }
        if(n%2 == 1){
            matrix[mid][mid] = count;
        }
        return matrix;
    }
}

###54. 螺旋矩阵

通过观察矩阵得出 有如下3种情况

1.矩阵长和宽相等,且都为偶数,这样在循环之后不需要额外判断
2.矩阵长和宽相等,且都为奇数,这样在循环之后,中间的点不会被计算进入,需要通过单独添加matrix[mid][mid]
**3.矩阵长宽不等,且最短的边为奇数,这样在循环之后,需要单独添加 一行或一列 **

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        int lenx = matrix[0].length;
        int leny = matrix.length;

        List<Integer> array = new ArrayList<>();

        int loop = Math.min(lenx,leny) >> 1;

        int offset = 1;

        int i , j;
        int x= 0,y=0;
        while(loop > 0){
            i = x;
            j = y;
            for(;j < lenx - offset; j ++){
                array.add(matrix[i][j]);
            }

            for(;i < leny - offset; i ++){
                array.add(matrix[i][j]);
            }

            for(;j >= offset; j--){
                array.add(matrix[i][j]);
            }

            for(;i >= offset; i--){
                array.add(matrix[i][j]);
            }

            x++;
            y++;
            loop--;
            offset ++;
        }
        // 行比列短 且行数为奇, 则单独录入 最中间的一列
        if(leny < lenx && (leny % 2 == 1)){
            j = x;
            i = y;
            for(;j <= lenx - offset; j ++){
                array.add(matrix[i][j]);
            }
        }
      // 列比行短 且列数为奇, 则单独录入最中间的一行
        if(leny > lenx && (lenx % 2 == 1)){
            j = x;
            i = y;
            for(; i <= leny - offset ; i++){
                array.add(matrix[i][j]);
            }
        }
      //行列相等 且都为奇数, 则单独录入最中间的一个元素
        if(leny == lenx && (lenx % 2 ==1)){
            int mid = lenx / 2;
            array.add(matrix[mid][mid]);
        }

        return array;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值