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

1 有序数组的平方

注意

有序的数组,平方后按要求排序

题目

在这里插入图片描述

解法

1.暴力解法

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;

    }
};

2.双指针

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int k = nums.size() - 1;
        vector<int> result(nums.size(), 0);
        for(int i = 0, j = k; i <= j ;){ // 需要有两个分号
            if(nums[i]*nums[i] >= nums[j]*nums[j]){
                result[k--] = nums[i]*nums[i];
                i++;
            }
            else{
                result[k--] = nums[j]*nums[j];
                j--;
            }
        }
        return result;
    }
};

基础知识补充

sort()函数使用。

  • sort() 函数位于 头文件中,用于对容器(如数组、向量等)进行排序。它提供了多种重载形式以适应不同的需求
  • C++ 的 sort() 函数默认按照升序进行排序。如果需要降序排序,可以在调用 sort() 函数时使用 greater<>() 或者自定义比较函数
#include <algorithm> // 导入头文件

// 用法1:对整个容器进行排序
sort(container.begin(), container.end());

// 用法2:对指定范围内的容器进行排序
sort(container.begin() + start_index, container.begin() + end_index);

// 用法3:使用自定义的比较函数进行排序
sort(container.begin(), container.end(), compare_function);

// 用法4:使用 lambda 表达式进行排序
sort(container.begin(), container.end(), [](const Type& a, const Type& b) {
    return a < b;
});
 - container 是你要排序的容器,如数组、向量等。 	
 - begin() 和 end() 分别指向容器的起始位置和结束位置。
 - start_index 和 end_index 指定了排序范围的起始和结束位置(不包括结束位置)。 	
 - compare_function是一个自定义的比较函数,用于指定排序规则。

2 长度最小的子数组

注意

连续的子数组

题目

在这里插入图片描述

解法

  1. 最初错误解法(理解错误了,需要连续子数组,不只是最少数组
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        // 先排序,然后从最大的开始与target进行比较
        sort(nums.begin(),nums.end());
        int k = 0;
        for(int j = nums.size() - 1; j >= 0; j--){
            k += nums[j];
            if(k >= target) return (nums.size() - j);
        }
        return 0;
    }
};

2.暴力解法【超时了】

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        // 两个循环,记录可行的子数组长度,并返回最小值 
        int sum = 0;
        int result = INT32_MAX;
        int jishu = 0;
        for(int i = 0; i < nums.size(); i++){
            sum = 0; // 不能在内循环if里,否则出现没有满足的子数组时sum会叠加
            for(int j = i ; j < nums.size() ; j++){
                sum += nums[j];
                if(sum >= target){
                    jishu = j - i + 1;
                    result = result > jishu ? jishu : result ;
                    break;
                }
            }
        }
        
        return result == INT32_MAX ? 0 : result;
        
    }
};

3.滑动窗口(里层的while循环是精髓)

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) { 
        int sum = 0;
        int result = INT32_MAX;
        int i = 0;
        int subLeng = 0;
        for(int j = 0 ; j < nums.size() ; j++){
            sum += nums[j];
            while(sum >= target){
                subLeng = j - i + 1;
                result = result > subLeng ? subLeng : result ;
                sum -= nums[i++]; //删除前指针指向的值,前指针并向前走一步
                //break;  // 如果大数组里面有小数组也满足,不会找到小数组,也就是不会找到最小的,比如 [1,4,4] 目标是4,一直会2个元素的数组滑动
            }  
        } 
        return result == INT32_MAX ? 0 : result; 
    }
};

基础知识补充

INT32_MAX 是int中最大值。

时间复杂度理解

  • 时间复杂度是一个函数,指的是随着输入大小的增长,运行时间会以怎样的速度扩张
  • O(logn),这里log特指log2,是该算法随着输入规模翻倍,操作次数只增加一

3 螺旋矩阵II

注意

寻找不变量

题目

在这里插入图片描述

解法

  1. 左闭右开
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> rec(n, vector<int>(n, 0));
        int startX = 0;
        int startY = 0;
        int loop = n / 2; //圈数,n为奇数时特殊处理
        int mid = n / 2; //特殊处理用的
        int offset = 1; // 左闭右开中开区间的应用
        int count = 1; //填充的元素
        int i,j;
        while(loop--){
            i = startX;
            j = startY;
            //左上到右上
            for(; j < n - offset; j++){
                rec[i][j] = count++;
            }
            //右上到右下
            for(; i < n - offset; i++){
                rec[i][j] = count++;
            }
            //右下到左下
            for(; j > startY; j--){
                rec[i][j] = count++;
            }
            //左上到左上
            for(; i > startX; i--){
                rec[i][j] = count++;
            }
            ++startX;
            ++startY;
            offset++;
        } 
        if(n % 2){
            rec[mid][mid] = count;
        }
        return rec;
    }
};

4 数组总结

参考:代码随想录总结

数据基础

  • 数组是存放在连续内存空间上的相同类型数据的集合
  • 在这里插入图片描述

5 感悟

有一些困难,第一遍刷重在理解了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值