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

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

[视频讲解](双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili)

[文档讲解](代码随想录 (programmercarl.com))


977

解题过程

先暴力再用双指针

双指针用的时候有一些小细节需要随时注意

暴力

先求平方再排序

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

双指针

// 双指针法
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int Head=0,Tail=nums.size()-1;
        vector<int> result(nums.size(),0);
        int mid=Head+(Tail-Head)/2;			//无需求中位
        int index =Tail;
        while(Head<=Tail){
                if(abs(nums[Head])<abs(nums[Tail])){
                    result[index--]=pow(nums[Tail],2);
                    Head++;		//错误点-->赋值之后把Tail指针往前挪
                }
                else{
                    result[index--]=pow(nums[Head],2);
                    Tail--;		//错误点 -->赋值之后应该把Head指针往后挪
                }
        }
        
        return result;
        }
};

正确解法

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int Head = 0, Tail = nums.size() - 1;
        vector<int> result(nums.size(), 0);
        int index = Tail;

        while (Head <= Tail) {
            if (abs(nums[Head]) < abs(nums[Tail])) {
                result[index--] = pow(nums[Tail], 2);
                Tail--;
            } else {
                result[index--] = pow(nums[Head], 2);
                Head++;
            }
        }

        return result;
    }
};

209 长度最小的子数组

暴力解

–错误

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int endret=INT16_MAX;			//这个地方必须用最大值
        int sum;
        int ret;			//不需要中间传值,两个传出就可以了
        for(int i=0;i<nums.size();i++){
            for(int j=0;j<nums.size();j++){		//这个地方的起始值一定是I  **重要
                
                if(sum<target){
                    sum+=nums[j];
                }
                else{
                    ret = j;
                    break;
                }
            }
            if(endret>ret){
                endret=ret;
            }
        }
        return endret;			//最后比对即可
    }
};

滑动窗口

  1. 初始化两个指针 startend,都指向数组的开始位置。
  2. 向右移动 end 指针,扩大窗口,直到窗口内的元素和大于或等于目标值 target
  3. 当窗口内的元素和满足条件时,尝试通过向右移动 start 指针来缩小窗口,同时更新最小长度。
  4. 重复步骤 2 和 3,直到 end 指针到达数组的末尾。
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int start=0;
        int sum=0;
        int len=INT_MAX;
        for(int end=0;end<nums.size();end++){
            sum+=nums[end];
            while(sum>=target){
                
                len=min(len,end-start+1);
                sum-=nums[start++];
                
            }
        }
        return len==INT_MAX?0:len;
    }
};

螺旋矩阵

·····无语题,脑子转不过来弯,写了一个小时才写明白

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
            std::vector<std::vector<int>> matrix(n, std::vector<int>(n));
    int startRow = 0, endRow = n - 1;
    int startCol = 0, endCol = n - 1;
    int num = 1;

    while (startRow <= endRow && startCol <= endCol) {
        // 填充上行
        for (int col = startCol; col <= endCol; col++) {
            matrix[startRow][col] = num++;
        }
        startRow++;

        // 填充右列
        for (int row = startRow; row <= endRow; row++) {
            matrix[row][endCol] = num++;
        }
        endCol--;

        // 填充下行
        if (startRow <= endRow) {
            for (int col = endCol; col >= startCol; col--) {
                matrix[endRow][col] = num++;
            }
            endRow--;
        }

        // 填充左列
        if (startCol <= endCol) {
            for (int row = endRow; row >= startRow; row--) {
                matrix[row][startCol] = num++;
            }
            startCol++;
        }
    }

    return matrix;
    }
};

总结

对双指针现在运用比较熟练,滑动窗口算是双指针的一个小应用吧,不是很难理解,最后的一道螺旋矩阵属实有点烦人,在每个位置上需要快速在脑子里模拟出来发生了什么事情。今日学习时长3.5H。B—打卡成功

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值