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

977.有序数组的平方

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

暴力解法:分两个小步,第一小步:把原来每个数组元素都变成自己本身的平方,第二小步:再对处理好的数据进行排序处理。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& A) {
        for (int i = 0; i < A.size(); i++) {
            A[i] *= A[i];
        }
        sort(A.begin(), A.end()); // 快速排序
        return A;
    }
};

双指针解法:已知给定的数组是有序的,且可能包含负数,假设不包含负数,那么最大值只可能在数组末尾出现,假设包含负数,那么最大值可能在开头,也可能在末尾,两种情况唯独不可能出现在中间,“中庸”现象。双指针的思路就是:一个指针指头部元素平方,一个指针指尾部元素平方,二者取其大者,从新数组的尾部开始插入然后那个大者的指针继续移动,小的不做改变。

int* sortedSquares(int* nums, int numsSize, int* returnSize){
    //返回的数组大小就是原数组大小
    *returnSize = numsSize;
    //创建两个指针,right指向数组最后一位元素,left指向数组第一位元素
    int right = numsSize - 1;
    int left = 0;

    //最后要返回的结果数组
    int* ans = (int*)malloc(sizeof(int) * numsSize);
    int index;
    for(index = numsSize - 1; index >= 0; index--) {
        //左指针指向元素的平方
        int lSquare = nums[left] * nums[left];
        //右指针指向元素的平方
        int rSquare = nums[right] * nums[right];
        //若左指针指向元素平方比右指针指向元素平方大,将左指针指向元素平方放入结果数组。左指针右移一位
        if(lSquare > rSquare) {
            ans[index] = lSquare;
            left++;
        } 
        //若右指针指向元素平方比左指针指向元素平方大,将右指针指向元素平方放入结果数组。右指针左移一位
        else {
            ans[index] = rSquare;
            right--;
        }
    }
    //返回结果数组
    return ans;
}

209.长度最小的子数组

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

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

暴力解法:用两个for解题目:第一个for确认数组起点,第二个for确认数组终止位置,思路不难理解,其中的细节值得扣一扣。

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int result = INT32_MAX; // 最终的结果
        int sum = 0; // 子序列的数值之和
        int subLength = 0; // 子序列的长度
        for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
            sum = 0;
            for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
                sum += nums[j];
                if (sum >= s) { // 一旦发现子序列和超过了s,更新result
                    subLength = j - i + 1; // 取子序列的长度
                    result = result < subLength ? result : subLength;
                    break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
                }
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == INT32_MAX ? 0 : result;
    }
};

滑动窗口解法:所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。 实际上滑动窗口也算是双指针解法的一种,但是想一个窗口一样,所以叫滑动窗口。可以发现滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。

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

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

解决螺旋矩阵的主要方法就是对条件进行判断,我们要保持条件判断的一致性,模拟顺时针画矩阵的过程:上行从左到右,右行从上到下,下行从右到左,左行从下到上。

/**
 * 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);
    int i;
    for(i=0;i<n;i++){
        ans[i]=(int*)malloc(sizeof(int)*n);
        (*returnColumnSizes)[i]=n;
    }
    int starX=0;
    int starY=0;
    int mid=n/2;
    int loop=n/2;
    int offset=1;
    int count=1;

    while(loop){
        int i=starX;
        int j=starY;
        for(;j<starY+n-offset;j++){
            ans[starX][j]=count++;
        }
        for(;i<starX+n-offset;i++){
            ans[i][j]=count++;
        }
        for(;j>starY;j--){
            ans[i][j]=count++;
        }
        for(;i>starY;i--){
            ans[i][j]=count++;
        }
        offset+=2;
        starX+=1;
        starY+=1;
        loop--;
    }
    if(n%2)
    ans[mid][mid]=count;
    return ans;
}

其中需要注意的是对边界条件的判断,还有如果n是奇数,中间就有一个单独的空缺,要单独拿出来判断

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值