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

977.有序数组的平方

第一想法是,对原数组元素进行绝对值排序再平方,或者先平方再排序。问题是如何排序?

看了讲解之后,明白自己忽视了题目中的原始要求:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。所以在排序方法上可以不用全部重新排序,可以利用它原有的格式,最大值只可能出现在最左端或者最右端,利用双指针方法对它进行排序。

冒泡排序

能通过测试样例,但是超出时间限制。

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

双指针(神一样好用精妙的思想)

关键点在于“有序数组”,本身给提供的数组就是按照顺序排列的,因此最大值最小值只有可能出现在两端,不会出现在中间。

int* sortedSquares(int* nums, int numsSize, int* returnSize){
    // returnSize代表返回的数组大小 这样处理
    *returnSize = numsSize;
    //因为返回的数组大小就是原数组大小
    
    int right =  numsSize - 1;
    int left = 0;
    
    //自己再定义一个数组作为最后返回的数组 通过以下的方式来定义
    int* ans = (int*)malloc(sizeof(int) * numsSize); 
    //意思是通过malloc这个动态规划内存的方式 为什么通过这种方式 别的方式不行吗 
    int i;
    for(i = numsSize - 1; i >= 0; i--){
        int l = nums[left] * nums[left];
        int r = nums[right] * nums[right];
        if(l > r){
            ans[i] = l;
            left = left + 1;
            //注意这里左右指针的加减 
        }
        else{
            ans[i] = r;
            right = right - 1;
            //注意这里左右指针的加减 
        }
    }
    return ans;
}
Dynamic Memory Allocation

动态规划是指运行时数据结构(比如数组)大小的改变。C语言提供了一些方法解决这个任务。4个定义在<stdlib.h>下的库函数:malloc()calloc()free()realloc()

malloc(m指Memory alloc指Allocation)可以动态规划出指定大小的一块独立大块内存,返回一个空类型指针(可以被转换为任何类型的指针),语法规则如下。

//Syntax:
ptr = (cast-type*) malloc(byte-size)
//Example:
int* ans = (int*)malloc(sizeof(int) * 100);
//int的大小是4字节,malloc会分配400个内存字节
//指针ans是内存字节的第1个字节
//如果空间不足,会返回空指针
https://www.google.com/amp/s/www.geeksforgeeks.org/dynamic-memory-allocation-in-c-using-malloc-calloc-free-and-realloc/amp/

209.长度最小的子数组

利用双指针思想

int minSubArrayLen(int target, int* nums, int numsSize){
    //初始化最小长度为INT_MAX
    int minLength = INT_MAX;
    int sum = 0;

    int left = 0, right = 0;
    //右边界向右扩展
    for(; right < numsSize; ++right) {
        sum += nums[right];
        //当sum的值大于等于target时,保存长度,并且收缩左边界
        while(sum >= target) {
            int subLength = right - left + 1;
            minLength = minLength < subLength ? minLength : subLength;
            sum -= nums[left++];
        }
    }
    //若minLength不为INT_MAX,则返回minLnegth
    return minLength == INT_MAX ? 0 : minLength;
}

59.螺旋矩阵II

通过一个while循环内嵌for循环解决螺旋填充数字问题。

引入了循环圈数loop变量,loop = n / 2

引入了偏移数offset

引入每次循环的起始位置startX startY

int** generateMatrix(int n, int* returnSize, int** returnColumnSizes){
    int nums[n][n];
    int s = 1;
    int i,j,k;
    //i为行数 j为列数 s为填充的数字 
    int startX = 0;
    int startY = 0;
    //每次循环的起始位置 
    *returnSize = n;
    *returnColumnSizes = (int*)malloc(sizeof(int) * n);
    int** ans = (int**)malloc(sizeof(int*) * n);
    int loop = n / 2;//循环的圈数
    int offset = 1;//偏移数
    for(i = 0; i < n; i++) {
        ans[i] = (int*)malloc(sizeof(int) * n);
        (*returnColumnSizes)[i] = n;
    }

    while(loop > 0){
        i = startX;
        j = startY;
        for( ; j < startY + n - offset; j++){
        ans[startX][j] = s;
        s++;
        }
        for( ; i < startX + n - offset; i++){
        ans[i][j] = s;
        s++;
        }
        for( ; j > startY; j--){
        ans[i][j] = s;
        s++;
        }
        for( ; i > startX; i--){
        ans[i][j] = s;
        s++;
        }
        //偏移值每次加2
        offset+=2;
        //遍历起始位置每次+1
        startX++;
        startY++;
        loop--;
    }
    
    if(n % 2 != 0){
        ans[n/2][n/2] = n * n;
    }
    return ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值