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

 LeeCode 977. 有序数组的平方

题目链接977.有序数组的平方

一遍过

注:1、不能在函数中声明定义一个数组,然后返回该数组,会报错“stack-use-after-scope”。具体的:malloc动态分配----内存是在堆区分配的,全局变量;而int a[N] 静态分配 ----存储区是在栈里分配的,局部变量。因此,如果想要想返回,必须用malloc动态分配。

2、结合题干灵活处理,本题待排序的元素非递增的,因此从数组尾部开始存储。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    *returnSize = numsSize;
    int left = 0, right = numsSize -1;
    int* ans = (int*)malloc(sizeof(int)*numsSize);
    int i = 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;
}

LeeCode 209.长度最小的子数组

题目链接209.长度最小的子数组

基本一遍过,中间出现了一个溢出,正如day1总结的,溢出一般是循环里的索引没有正确增减导致的。

注:1、滑动窗口,滑动窗口的关键在于窗口左右边界的动态判定。

2、更新最小窗口长度

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

LeeCode 59.螺旋矩阵II

题目链接59.螺旋矩阵II

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes) {
    *returnSize = n;
    *returnColumnSizes = (int*)malloc(sizeof(int) * n);
    int** ans = (int**)malloc(sizeof(int*) * n);
    for (int i = 0; i < n; i++) {
        ans[i] = (int*)malloc(sizeof(int) * n);
        (*returnColumnSizes)[i] = n;
    }
    int startX = 0, startY = 0;
    int offset = 1;
    int loop = n / 2;
    int middle = n / 2;
    int count = 1;
    while (loop--) {
        int i = startX, j = startY;
        for (; j < n - offset; j++) {
            ans[i][j] = count++;
        }
        for (; i < n- offset; i++) {
            ans[i][j] = count++;
        }
        for (; j > startY; j--) {
            ans[i][j] = count++;
        }
        for (; i > startX; i--) {
            ans[i][j] = count++;
        }
        startX++;
        startY++;
        offset++;
    }
    if (n % 2) {
        ans[middle][middle] = count;
    }
    return ans;
    
}

注:

1、*小错误:对可能的中间位置赋值的判断条件错误,应该是if (n % 2),而非if (n / 2);

2、正如day1所指出的,一定要明确每一次循环变量的边界,比如startX、startY和offset,并且要贯彻“左闭右开”的思想;

3、本质还是双指针,所以遇到一个题目,应该先思考是否可以双指针法;

4、**returnColumnSizes和**ans的理解:

对于**returnColumnSizes:要传递的是的是一个数组,这个数组存储了每一列的尺寸,因此需要传递进来的是一个数组指针的地址(或者说是一个数组指针的指针),即**returnColumnSizes

那么*returnColumnSizes就是这个这个数组指针的内容,即数组的地址类似于 int a[N]中的a,因此(*returnColumnSizes)[i]类似于a[i],即数组的内容。

对于**ans:作为返回值,实际上返回的是一个二维数组,所以方法就是:开辟空间用于存储多个一维数组的指针,然后再让ans指向这片空间。具体的:

int **ans = (int**)malloc(sizeof(int*) * n);//这里malloc开辟了一片用于存储n个整形指针的空间,这里ans本质上还是一个一维数组,只不过数组存储的是整形指针的地址。

...

ans[i] = (int*)malloc(sizeof(int) * n);//这里用for(...)循环开辟这n个整形指针指向的空间,ans[i],即代表ans的第i个空间存储的内容是一个指针。

day2的思考

双指针是好东西

写代码的时候先想清楚思路,写关键代码,声明需要的变量,最后完善边界和检查

通过59题,反复揣摩一个全局的二维数组建立的方法,和如何将一个一维数组的指针的地址传入函数

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值