代码随想录训练营day2|LeetCode 977有序数组的平方、209长度最小的子数组、59螺旋矩阵 II

977.有序数组的平方

题目链接:力扣-977.有序数组的平方

思路:

第一眼看到这道题,就想到了用昨天学的双指针法,很可惜编译失败,看完卡哥的视频之后,知道自己卡在了什么地方,没有想到数组中的元素可能为负数。了解完具体思路后,立马动手去编写程序,成功通过了编译。

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

i指向起始位置,j指向终止位置。

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

如果A[i] * A[i] < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。

如果A[i] * A[i] >= A[j] * A[j] 那么result[k--] = A[i] * A[i]; 。

如动画所示:

卡哥视频链接:https://www.bilibili.com/video/BV1QB4y1D7ep

文章讲解:代码随心录

代码:

int* sortedSquares(int* nums, int numsSize, int* returnSize){
    *returnSize = numsSize;
    int* ans = (int*)malloc(sizeof(int) * numsSize);
    int i = numsSize - 1;
    int left = 0;
    int right = numsSize - 1;
    while(left <= right){
        if(nums[left] * nums[left] > nums[right] * nums[right]){
            ans[i--] = nums[left] * nums[left];
            left++;
        }
        else{
            ans[i--] = nums[right] * nums[right];
            right--;
        }
    }
    return ans;
    
}

力扣上有一个总结的很好的题解,利用了多种排序和双指针的方法,先贴出来供大家一起学习,正好能复习以下各种排序算法。

https://leetcode.cn/problems/squares-of-a-sorted-array/solutions/39242/ge-chong-pai-xu-shuang-zhi-zhen-by-toxic-3/

209.长度最小的子数组

 题目链接:力扣-209. 长度最小的子数组

思路:

这道题曾经做过,如今再来做依然写不出来......

思考了十几分钟无思路后,继续看卡哥视频讲解学习。

该题有两种解法,一种是暴力解,第二种是利用滑动窗口的方法来解题,这也是数组中比较重要的解法,个人感觉像是暴力解法的优化,还是用到了两个循环,看视频时有弹幕说可以用if,暂时还没想出来,明天再看看。

所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。

 

图示更能方便理解,照例附上卡哥视频及文章讲解链接。

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

大致思路是,先固定滑动窗口的起始位置 i ,用终止位置 j 进行索引,当该区间内所有元素相加大于等于目标数时,移动起始位置 i 。若新区间元素之和小于目标数,则继续移动 j ,直到大于等于目标数。重复以上操作,直到寻找到长度最小的子数组。

代码:

int minSubArrayLen(int target, int* nums, int numsSize){
    int ans = INT_MAX;
    int left = 0;
    int right = 0;
    int sum = 0;
    for(; right < numsSize; right++){
        sum += nums[right];
        while(sum >= target){
            int length = right - left + 1;
            ans = ans < length? ans : length;
            sum -= nums[left++];
        }
    }
    return ans == INT_MAX? 0 : ans;
}

59螺旋矩阵II

题目链接:力扣-59. 螺旋矩阵 II

思路:

看到这个题时确实没什么思路,看完视频和文章讲解后,能理解思路,但还不能完全写出完整代码来,打算明天再仔细琢磨一下。

附上学习的链接:

https://www.bilibili.com/video/BV1SL4y1N7mV

代码:

int** generateMatrix(int n, int* returnSize, int** returnColumnSizes){
    //初始化返回的结果数组的大小
    *returnSize = n;
    *returnColumnSizes = (int*)malloc(sizeof(int) * n);
    //初始化返回结果数组ans
    int** ans = (int**)malloc(sizeof(int*) * n);
    int i;
    for(i = 0; i < n; i++) {
        ans[i] = (int*)malloc(sizeof(int) * n);
        (*returnColumnSizes)[i] = n;
    }

    //设置每次循环的起始位置
    int startX = 0;
    int startY = 0;
    //设置二维数组的中间值,若n为奇数。需要最后在中间填入数字
    int mid = n / 2;
    //循环圈数
    int loop = n / 2;
    //偏移数
    int offset = 1;
    //当前要添加的元素
    int count = 1;

    while(loop) {
        int i = startX;
        int j = startY;
        //模拟上侧从左到右
        for(; j < startY + n - offset; j++) {
            ans[startX][j] = count++;
        }
        //模拟右侧从上到下
        for(; i < startX + n - offset; i++) {
            ans[i][j] = count++;
        }
        //模拟下侧从右到左
        for(; j > startY; j--) {
            ans[i][j] = count++;
        }
        //模拟左侧从下到上
        for(; i > startX; i--) {
            ans[i][j] = count++;
        }
        //偏移值每次加2
        offset+=2;
        //遍历起始位置每次+1
        startX++;
        startY++;
        loop--;
    }
    //若n为奇数需要单独给矩阵中间赋值
    if(n%2)
        ans[mid][mid] = count;

    return ans;
}

总结

今天的题总体难度很大,加上今天时间有限,这篇博客写得不是很好,明天我会抽出时间来好好总结完数组的所有题目,包括附加题,对这两天的博客再度更新,将题目都重新归纳整理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值