代码随想录算法训练营第二天|LeetCode977 有序数组的平方 LeetCode209 长度最小的字符串 LeetCode59 螺旋矩阵II 以及数组总结

本文详细介绍了作者在算法训练营第二天遇到的LeetCode题目,包括977有序数组的平方、209长度最小的连续子数组、59螺旋矩阵II的解题思路和代码实现。作者通过双指针法和滑动窗口解决数组问题,并总结了数组算法的学习心得,如二分法和双指针法的应用技巧。
摘要由CSDN通过智能技术生成

LeetCode977

题目链接:力扣977

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

个人思路:对题目所给定的数组使用双指针法,一个指针指向开头,一个指针指向末尾,然后这两个指针的比较思路是,当左指针指的值平方大于右指针,则将这个数赋给新的数组,并且新数组的元素是从最右边开始排序的,若不大于右指针的值,则将右指针的值赋给新的数组。此外,每赋一次值,要么是左边的指针移动,或者右边的指针移动,不可以两个指针一起移动,循环判断条件是新数组的指针Index大于0。因此还需要创建一个新的数组,新数组的长度等于题目所给定数组的长度,此外还需要一个指针指向新数组的末尾,每一次循环,新指针都要移动,因此新指针是判断条件。

个人错误点:第一次是将判断条件为左指针遍历数组,错误的输出结果是,输出的数组会显示不完全,就是有其它的数没有显示出来。第二次是在赋值过程中,左右的指针同时移动,后果也是没有显示所有的数。

代码如下:

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

LeetCode209

题目链接:力扣209

题目要求:

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

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

个人思路:本题使用滑动窗口来求解,就是用一个指针index指向数组的头部,然后开始遍历数组,此外每遍历一个元素都要进行求和,求和完毕之后进行判断,判断是否大于目标值,如果大于目标值,则将这个时候的长度记录下来,然后对滑动窗口进行缩减,怎么缩减呢,那就要用另一个指针left来完成这个操作,就是用求和的值减去left指针指向的这个数,减完之后对其让left指针向右移动,从而达成一种动态的窗口的效果

具体效果如下图所示:

这是刚到目标值的时候然后下一个缩减图是这样的:

因为这个时候求和出来的值小于目标值,因此index指针向左移动,left指针不动,再下一个图是这样的:

 

 往复循环,最后代码如下图:

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

在自己写的过程中出现了错误,我是用if加for循环来写的,没写出来,然后看了题解,我的错误代码如下:

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

先记录自己的错误,等有时间回头看自己的错误,这里的思路应该是先利用双指针,一个指针去遍历数组,等到求和的值大于目标值的时候,再缩减窗口,在第二个for循环里面,我又创建了一个新的指针,它的意义在于缩减窗口,就好像这样,index指针此时指向下标为3的元素,这个时候累加值已经大于目标值,我缩减完数组之后发现小于目标值,退出循环,然后我的想法是index指针再从下标为1的位置开始遍历,一开始是下标为0开始遍历,等到求和值大于目标值的时候就缩减数组,然后是下标为1开始遍历......从而遍历完整个数组

LeetCode59

题目链接:力扣59

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

个人思路:其实就是对于代码的逻辑能力,和算法无关,此题我错误的地方有几点,第一个是需要有一个循环初始点,这个点是每一次循环的时候作为初始位置处理,所以第一圈循环或者之后每圈的循环都是以初始点作为行来开始,不然的话,找不到初始点,之后的值会给覆盖,第二个错误的地方在于进入循环的时候的判断条件,基本每个判断条件我都错了,正确的判断条件是这样的,代码如下:

for( i = start;i<n-loop;i++)

for( j = start;j<n-loop;j++)

for(;i>=loop;i--)

for(;j>=loop;j--)

而我的循环判断条件是这样的,代码如下:

for( i = start;i<n-1;i++)

for( j = start;j<n-1;j++)

for(;i>loop-1;i--)

for(;j>loop-1;j--)

很清楚的可以看到,对于我错误的地方,只是单纯的减一的话,如果有两圈循环,那么第二圈的循环还是和第一圈的循环一样,就是说,第二圈的循环本来,本来是应该比第一圈的数字要少的,但是由于我判断的条件只是单纯的减一,因此,第一圈和第二圈的数会一样多,至于后面的loop-1,好像没错,不太确定,有空看看。

总结数组算法:

数组算法到目前看来,只学习掌握了,二分法,二分法需要注意查找边界的问题,本质上还是二分法那一套,不同的是对于目标值等于中间值的时候该怎么处理;双指针法,双指针法包括了一个指向开头,一个指向末尾(力扣977)、以及两个同时指向开头(力扣27),以及最后的矩阵,矩阵emm看个人思维能力,多写就能A出来。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值