代码随想录第二天|有序数组的平方|寻找最短子数组的长度|螺旋数组Ⅱ

977. 有序数组的平方

文档讲解:代码随想录
视频讲解:B站视频
状态:查阅文档后AC

本文主要介绍双指针法,由于输入数组有序,但是平方后的数组可能会与原数组排序不同,因此我们采用一个新数组来存储有序数组的平方。有序数组平方后,数组两侧的值大于数组中间的值,因此,采用两个指针由数组两侧指向数组中间。指针的行为如下:

两个指针所指向的元素比较大小,较大的那个元素按添加进新数组的末尾,然后指向较大的一侧的指针向中间移动
即,两个指针在一次操作中只会有一个进行移动,也只会有一个元素被放入新数组中,直到两个指针指向相遇,也就是left = right时,必定放入最小的元素,while循环的条件应该为left <= right。另外也可以使用for循环进行遍历,这样更方便将数据写入新数组。使用for循环的整体代码如下:

class Solution {
    public int[] sortedSquares(int[] nums) {
        int left = 0, right = nums.length - 1;
        int[] result = new int[nums.length];
        for (int k = nums.length - 1; k >=0; k--) {
            int ls = nums[left] * nums[left], rs = nums[right] * nums[right];
            if(ls > rs) {
                result[k] = ls;
                left ++;
            }
            else {
                result[k] = rs;
                right --;
            }
            
        }
        return result;
    }
}

209. 长度最小的子数组

文档讲解:代码随想录
视频讲解:B站视频
状态:在得知采用滑动窗口之后,尝试将窗口左侧指针遍历数组元素,但是复杂度与暴力解法相同,查看文档后,将窗口右侧指针作为遍历元素的索引之后AC

题目隐含两个要求:

  1. 找出子数组之和大于等于目标值的子数组
  2. 在这些满足条件的子数组中找出长度最小的子数组长度(注意:不要求返回最小子数组)

本文介绍滑动窗口方法,使用两个指针分别指向滑动窗口的左端和右端,由于要求寻找长度最小的子数组,因此滑动窗口从零开始增长,初始都指向数组的第一个元素,右侧指针作为索引进行遍历,左侧指针用于在满足条件1后记录满足条件的子数组长度并对滑动窗口收缩寻找下一个满足条件的子数组。

将当前的子数组长度与所记录的最小子数组长度进行对比,遍历后即可得到长度最小的子数组。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0, right;
        int sum = 0;
        int sublen;
        int result = Integer.MAX_VALUE;
        for ( right = 0; right < nums.length; right++) {
            sum += nums[right];
            while (sum >= target) {
                sublen = right - left + 1;
                result = result > sublen ? sublen : result;
                sum -= nums[left ++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}

59. 螺旋数组Ⅱ

文档讲解
B站视频
状态:对于模拟螺旋所需要保存的变量十分懵逼,进行边界条件的判断标准也很不清晰,在看过文档和视频后尝试做出来了。从这道题也可以看出自己对于代码的掌控能力较弱,无法使用代码模拟一些简单的过程,这一部分需要加强锻炼。

这道题在日后复习时所需要注意的点我认为有以下几点:

  1. 在进行模拟时需要注意每次螺旋遍历二维数组所需要的坐标数据,这里使用startx, starty体现
  2. 每一圈遍历与上一圈遍历的不同,这里使用变量offset体现
  3. 每一条边遍历的区间,这里体现在for循环体中
  4. 遍历的大体流程,这里是以螺旋的圈为单位(while),每一圈由四条遍历长度相同数组的for循环组成

遍历每一条边使用如下顺序,并且采用左闭右开的区间进行遍历:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

因此每条for循环遍历数组时,从上至下依次是

  • startx不变,递增列坐标,并将遍历完的y坐标赋值给starty
  • starty不变,递增行坐标,并将遍历完的x坐标赋值给startx
  • startx不变,递减列坐标,并将遍历完的y坐标赋值给starty
  • starty不变,递减行坐标,并将遍历完的x坐标赋值给startx

遍历完一圈后,startx需要递增一个单位。具体代码如下:

class Solution {
    public static int[][] generateMatrix(int n) {
        int [][]result = new int[n][n];
        int circout = n / 2;
        int startx = 0, starty = 0;
        int counter = 1;
        int offset = 1;
        while (circout > 0) {
            // top
            for (int j = starty; j < n - offset; j++) {
                result[startx][j] = counter++;
                starty = j;
            }
            starty++;
            // right
            for (int i = startx; i < n - offset; i++) {
                result[i][starty] = counter++;
                startx = i;
            }
            startx++;
            // bottle
            for (int j = starty; j > offset - 1; j--) {
                result[startx][j] = counter++;
                starty = j;
            }
            starty--;
            // left
            for (int i = startx; i > offset - 1 ; i--) {
                result[i][starty] = counter++;
                startx = i;
            }
            starty ++;
            circout --;
            offset ++;
        }
        if (n % 2 == 1) result[n/2][n/2] = counter;
        return result; 
    }
}
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值