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

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

时间:2022-11-18 00:56:05浏览次数:70  
标签:977 right nums int res 随想录 ++ 数组

977.有序数组的平方

题目建议: 本题关键在于理解双指针思想

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/

文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html

视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep

思路想法:1)非递减排好的数组,则非负数部分直接返回数字平方值就为非递减顺序

2)负数部分,由于也是按非递减排列,则直接平方后为非递增顺序

3)需要考虑,将负数部分的平方插入到非负数平方返回后的数组中合适位置

然而写不出来.....

暴力:

第 1 步:一层 for 循环遍历数组,将各元素平方后存入数组,这一步的时间复杂度为 O(n)。

第 2 步:快排,时间复杂度为 O(nlogn)。

总的时间复杂度显然是 O(n + nlogn)

 

class Solution {
    public int[] sortedSquares(int[] nums) {
        for(int i= 0;i< nums.length;i ++){
            nums[i] *=nums[i];
            }
        Arrays.sort(nums);
        return nums;
    }
}

 

双指针

思路:

数组其实是有序的, 只不过负数平方之后可能成为最大数了。

那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。

此时可以考虑双指针法了,i指向起始位置,j指向终止位置。

定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。

 

看思路自己写,然后调试,code如下:

 

class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] sortedNums = new int[nums.length];
        int left = 0;
        int right = nums.length - 1;
        int index = nums.length - 1;
        while(left <= right){
            if(nums[left] * nums[left] < nums[right] * nums[right]){
                sortedNums[index] = nums[right] * nums[right];
                right --;
            }else{
                sortedNums[index] = nums[left] * nums[left];
                left ++;
            }
            index --;
        }
        return sortedNums;
    }
}

 

参考答案:

class Solution {
    public int[] sortedSquares(int[] nums) {
        int right = nums.length - 1;
        int left = 0;
        int[] result = new int[nums.length];
        int index = result.length - 1;
        while (left <= right) {
            if (nums[left] * nums[left] > nums[right] * nums[right]) {
                // 正数的相对位置是不变的, 需要调整的是负数平方后的相对位置
                result[index--] = nums[left] * nums[left];
                ++left;
            } else {
                result[index--] = nums[right] * nums[right];
                --right;
            }
        }
        return result;
    }
}

学习简洁的代码

class Solution {
    public int[] sortedSquares(int[] nums) {
        int l = 0;
        int r = nums.length - 1;
        int[] res = new int[nums.length];
        int j = nums.length - 1;
        while(l <= r){
            if(nums[l] * nums[l] > nums[r] * nums[r]){
                res[j--] = nums[l] * nums[l++];
            }else{
                res[j--] = nums[r] * nums[r--];
            }
        }
        return res;
    }
}

 

209.长度最小的子数组

题目建议: 本题关键在于理解滑动窗口

题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/

文章讲解:https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html

视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE

思路想法:

滑动窗口,窗口值初始为1,逐渐递增,自左向右滑动,查看窗口内之和是否满足条件

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int win = 1;
        while (win < nums.length + 1){
            for(int l = 0;(l + win -1 ) < nums.length;l ++){
                int r = l + win -1;
                int res = 0;
                while(l <= r){
                    res += nums[l++];
                    if(res >= target){
                        return win;
                    }
                }
        }
        return 0;
    }
}

超时

在本题中实现滑动窗口,主要确定如下三点:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。

窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int res = Integer.MAX_VALUE;
        int left = 0;
        int sum = 0;
        for(int right = 0;right < nums.length;right++){
            sum += nums[right];
            while(sum >= target){
                res = Math.min(res,right - left + 1);
                sum -= nums[left++];
            }
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

总结:知道大概思路,写不出来=。=

59.螺旋矩阵II

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

题目链接:https://leetcode.cn/problems/spiral-matrix-ii/

文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html

视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/

想法思路:

n行n列,自左向右:第一行为1到n;自上到下:第n列为n到2n-1(n+n-1); 自右向左:第n行为2n-1(n+n-1)到3n-2(n+n-1+n-1);自下到上:第一列为3n-2(n+n-1+n-1)到4n-4(n+n-1+n-1 + n-1-1)

不会

看答案:左闭右开、左闭右开、左闭右开!!!

转n/2圈,

 

class Solution {
    public int[][] generateMatrix(int n) {
        int loop = 0;  // 控制循环次数
        int[][] res = new int[n][n];
        int start = 0;  // 每次循环的开始点(start, start)
        int count = 1;  // 定义填充数字
        int i, j;

        while (loop++ < n / 2) { // 判断边界后,loop从1开始
            // 模拟上侧从左到右
            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;
    }
}

先打个卡,2022年11月18日00:39:31,明天再研究

 

标签:977,right,nums,int,res,随想录,++,数组
From: https://www.cnblogs.com/gaoyuan2lty/p/16901911.html

相关文章

  • Day15:数组的使用
    数组的使用普通的for循环打印所有数组元素打印数组元素最大值求和数组元素//打印数组元素publicclassDemo{publicstaticvoidmain(String[]args){......
  • 冒泡排序法2.0版本,加输入、输出数组字符串
    大家晚上好呀,今天给大家带来的是冒泡排序法的代码,首先我们以一些简单的数字来举例,根据昨天已有的知识点,我们可以利用二重循环写出基本代码,如图但是我这个有问题,但我目前还没......
  • javascript-代码随想录训练营day2
    59.螺旋矩阵Ⅱ题目链接:https://leetcode.cn/problems/spiral-matrix-ii/题目描述:给你一个正整数n,生成一个包含1到n2所有元素,且元素按顺时针顺序螺旋排列的nxn......
  • Hook代替类组件(hook+函数组件)
    Hook是React16.8的新增特性,它可以在不编写类组件的情况下使用state以及其他React特性Hook和函数组件:React的函数组件处理是这样的constDemo=(props)=>{//可......
  • 代码随想录算法训练营Day02|977.有序数组的平方、209.长度最小的子数组、59. 螺旋矩阵
    代码随想录算法训练营Day02|977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II977.有序数组的平方题目链接:977.有序数组的平方首先还是仔细审题,题目给出的数......
  • 代码随想录Day26
    LeetCode513.找树左下角的值      思路:思路1:需要遍历所有路径,找出深度最大的一条路径,并且是左叶子结点的值。思路2:层序遍历最左值。 递归遍历写法:前序......
  • LeetCode刷题(4)【移除元素&合并两个有序数组】(C语言)(含图解)
    移除元素典型双指针玩法。27.移除元素-力扣(LeetCode)(leetcode-cn.com)我们都会想到这样的解法:从前面依次往后推,是val就将该数据后面的元素依次覆盖上来,但是这样的时间复......
  • javascript js 对象数组 转json 数组解构
           ......
  • 04-Java-数组
    Java-数组一个类型所有数据的有序集合每个数据称作一个数组元素,通过每个组的元素可以用下标访问它数组是声明与创建首先必须声明数组变量,才能在程序种使用数组。d......
  • 数组指针和指针数组?
    首先,理解一下数组指针和指针数组这两个名词:“数组指针”和“指针数组”,只要在名词中间加上“的”字,就知道中心了——数组的指针:是一个指针,什么样的指针呢?指向数组的指针......