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

 977.有序数组的平方

 题目链接:力扣

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

示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

示例 2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

思考过程

  • 先平方,再排序
  • 视频思路:新开一个容器,利用双指针,两个指针分别指向头和尾,两者平方后比较,哪个大就放入容器尾部,然后向中间靠拢。最后情况是两指针指向同一个元素。
方法一:插入排序
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int i,j;
        for(i = 0;i < nums.size();i++){
            nums[i] = nums[i] * nums[i];
        }
        //插入排序
        int first_unsorted,position,current;
        for(first_unsorted = 1;first_unsorted < nums.size();first_unsorted++){
            //如果比前一个元素小,后面的元素整体后移,把小元素放到前面去
            if(nums[first_unsorted] < nums[first_unsorted - 1]){
                position = first_unsorted;
                current = nums[first_unsorted]; //暂存
                do{
                    nums[position] = nums[position - 1];
                    position--;
                }while(position > 0 && nums[position - 1] > current);
                nums[position] = current;
            }
        }
        return nums;
    }
};

方法二:sort函数

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

方法三:双指针

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
       int k = nums.size() - 1;
       vector<int>result(nums.size(),0); //初始化长度为nums.size()的容器
       for(int i = 0, j = nums.size() - 1;i <= j;){ //i==j的时候为双指针同时指向最后一个元素
           //哪个大就放入result,i,j两个指针相应向中间靠拢
           if(nums[i] * nums[i] < nums[j] * nums[j]){ 
               result[k--] = nums[j] * nums[j];
               j--;
           }
           else{
               result[k--] = nums[i] * nums[i];
               i++;
           }
       }
       return result;
    }
};

 209.长度最小的子数组

题目链接: 力扣

思考过程

  • 双重for循环遍历
  • 视频思路:双指针,j为快指针向右扫,超过target再把i减掉,往后移动

双指针 

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int i = 0;
        int sum = 0;
        int subl = 0;
        int result = INT32_MAX; //取一个最大值好比较
        for(int j = 0;j < nums.size();j++){
            sum += nums[j];
            while(sum >= target){ //大于等于就不断更新
                subl = j - i + 1; //取子序列长度
                result = result > subl ? subl : result;
                sum -= nums[i++]; //每次都把前面的减掉,等同于双重for循环
           }
        }
        return result == INT32_MAX ? 0 : result;
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

59.螺旋矩阵II 

题目链接: 力扣

 思考过程

  • 混乱
  • 视频思路:左闭右开,使用startx,starty两个作为每圈的固定节点,用offset减掉后就变为新的循环
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>>res(n,vector<int>(n,0)); //使用vector定义一个二维数组
        int startx = 0,starty = 0; //定义每循环一个圈的起始位置
        int loop = n / 2; //每个圈循环几次
        int mid = n / 2; //矩阵中间的位置,为了奇数情况设置
        int count = 1; //给矩阵中每一个空格赋值
        int offset = 1; //控制每一条边遍历的长度,每次循环右边界收缩一位
        int i, j;
        while(loop--){
            i = startx;
            j = starty;

            //下面四个for循环就是模拟转了一圈,左闭右开
            //上行从左到右
            for(j = starty; j < n - offset; j++)
                res[startx][j] = count++;
            //右列从上到下
            for(i = startx; i < n - offset; i++)
                res[i][j] = count++;
            //下行从右到左
            for(; j > starty; j--)
                res[i][j] = count++;
            //左列从下到上
            for(; i > startx; i--)
                res[i][j] = count++;
            //第二圈开始的时候,起始位置各自加上1
            startx++;
            starty++;
            //每一圈里每一条边遍历的长度
            offset++; 
        }
        if(n % 2 == 1)
            res[mid][mid] = count;
        return res;
    }
};
  • 时间复杂度 O(n^2): 模拟遍历二维矩阵的时间
  • 空间复杂度 O(1)

 

时间复杂度

O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n{!}) < O({n}^n

 滑动窗口

滑动窗口适用范围:

顺序不可变的数组Array中找 连续子数组 array

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值