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

顺序:
1.先自己敲代码发现不会
2.看思路题解,不要看具体代码
3.再敲,看能不能通过,找问题
4.发现还是不想,对比看具体代码

977.有序数组的平方

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

想法:暴力解法,先将数组中所有元素平方后存入其中,然后在暴力排序一遍。

错误
1.对排序算法不熟悉,导致排序算法错误。可以复习一下数据结构
代码
2.数组越界应该找框内的元素是否越界
3.if if 和if else 的区别:因为两个并列的 if 第一个if如果执行了 i 的位置发生了变化 然后如果变化后的i位置使得第二个if条件满足了 那么第二个if里的内容也会执行 但是slow没有变 slow位置的值就被覆盖了
4.leetcode中输出注意returnsize,不然会只能输出“]”。

文章讲解: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

正确解法

1.暴力解法
在这里插入图片描述
2.双指针法
理解这样一个带负数的升序数组,平方后升序排序最大的数只可能是从两边出,越到中间部分平方最小。在这里插入图片描述

1)以numsize为界限,将nums全部填满

int* sortedSquares(int* nums, int numsSize, int* returnSize){
    int*result=malloc(sizeof(int)*numsSize);
    int i=0;
    int j=numsSize-1;
    int slow=numsSize-1;
    for(slow;slow>=0;slow--){
        if(nums[i]*nums[i]>=nums[j]*nums[j])
           { 
               result[slow]=nums[i]*nums[i];
                    i++;
            }
        if(nums[i]*nums[i]<nums[j]*nums[j])
            {
                result[slow]=nums[j]*nums[j];
                j--;
                }
    }
        *returnSize=numsSize;
        return result;
}

2)左右两指针相逢为界限

k=numsize-1;	
for(i=0,j=numsize-1;i<=j;){//i为前指针,j为后指针,(注意j=numsize-1,而不是numsize,当i与j相逢时表示新数组已满,相等时那个数也要取到,i、j变化由数据不同而不同)
	if(nums[i]*nums[i]>nums[j]*nums[j]){
	 result[k--]=nums[i]*nums[i];
	 i++;
	}
	else{//不能再用if;
		result[k--]=nums[j]*nums[j];
		j--;
	}
```步骤
1.设置新数组的坐标值,由于该题双指针的思想,从后面开始填充新数组
2.以i,j相逢或者新数组填满为临界条件
3.判断两端那一边更大,将更大端填入新数组,然后移动该端的指针

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

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

想法
两个循环依次全部遍历所有的组合,但不能找出最小组合在这里插入图片描述
解法:
暴力解法:在这里插入图片描述
巧妙之处:专门用result表示最后的结果,每次找到一个符合条件的lens即与result比较,找出正确的result,注意最后的return result == INT32_MAX ? 0 : result;的写法
在这里插入图片描述
滑动窗口法
相信大家有遇到过这种情况: 感觉题目的边界调节超多,一波接着一波的判断,找边界,拆了东墙补西墙,好不容易运行通过了,代码写的十分冗余,毫无章法,其实真正解决题目的代码都是简洁的,或者有原则性的,大家可以在这道题目中体会到这一点。在这里插入图片描述
上面的指针始终指向第一个元素,直到下面的指针移动到从第一个指针到下面指针指向元素的和大于等于目标值时,记录长度,使和删除上面指针指向的元素后,在将上指针向后移动,若符合上指针到下指针所指元素和大于目标值,记录比较长度,如此循环

看视频讲解后错解
在这里插入图片描述
因为我把result最大值定为999,而在测试数列中有比999更大的正确答案。
注意INT_MAX;在C中可作为一个无穷大的数
在这里插入图片描述

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为奇数时会剩下中心的一个数组元素没有遍历到

nums[i][j]按顺序填充是j先填充,再i++;
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值