随想录训练营2/60 | LC 977 有序数组的平方;LC 209 长度最小子数组; LC 59 螺旋矩阵||

LC 题目

题目链接LC 977 有序数组的平方
思路双指针法,两个指针分别指向数组的头尾,向中间遍历。每次遍历比较数组两数的平方大小,把大的数放在新数组的最后,新数组从后向前遍历。
代码

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> result(nums.size(), 0);//创建大小为nums.size(),初始值为0的vector
        int l = 0;
        int r = nums.size()-1;
        for(int j=result.size()-1; j>=0; --j){
            if(nums[l]*nums[l]>=nums[r]*nums[r]){
                result[j] = nums[l]*nums[l];
                ++l;
            }
            else{
                result[j] = nums[r]*nums[r];
                --r;
            }
            if(l>r)break;
        }
        return result;

    }
};

题目链接LC 209 长度最小子数组
思路滑动窗口,窗口的大小是动态的,借用双指针的思想,指针指向窗口的起始和末尾。首先尾指针向后遍历,直到窗口内的值大于等于target,若比之前窗口长度小则记录窗口长度;然后首指针向后遍历,若窗口内的值仍大于等于target且长度小于旧的则记录新长度,若窗口值小于target则后指针向后遍历(重复开始的步骤)。
代码

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int l = 0;//窗口的开始
        int r = 0;//窗口的末尾
        int sum = 0;//窗口内的值的总和
        int minLen = INT32_MAX;//记录滑动窗口的最小值
        int len = 0;//记录滑动窗口的大小
        while(r<nums.size()){//当r遍历到数组的最后一个的后面时,跳出循环
            sum = sum + nums[r];//从末尾扩大滑动窗口范围
            ++len;
            ++r;
            while(sum>=target){//当窗口内的值大于等于target时开始从窗口开头收缩窗口
                if(minLen>len)minLen = len;//记录最小的窗口长度
                sum = sum - nums[l];
                ++l;
                --len;
            }
        }
        minLen = minLen == INT32_MAX ? 0 : minLen; 
        return minLen;
    }
};

题目链接LC 59 螺旋矩阵||
思路:需要注意两点,第一螺旋矩阵从外往内每一层的每条边的区间(上:左闭右开;右:上闭下开;下:右闭左开;左:下闭上开);第二螺旋矩阵最大边长若为偶数则无需考虑最中心的元素,若为奇数需特殊考虑给中心元素赋值。
代码

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
    vector<vector<int>> result(n, vector<int> (n, 0));//定义并初始化返回值
    int mid = n/2;//若n为偶数则无用,若n为奇数则矩阵中[mid,mid]位置的值为n*n
    int len = n;//每圈的边长
    int loop_i = 0;//用来遍历整个矩阵,每一圈的起点坐标,eq[0,0],[1,1]...
    int loop_j = 0;
    int val = 1;//从1到n*n给矩阵赋值
    while(len>1){//边长为1特殊讨论
        int i = 0;
        int j = 0;
        for(;j<len-1;j++){
            result[i+loop_i][j+loop_j] = val;
            ++val;
        }
        for(;i<len-1;i++){
            result[i+loop_i][j+loop_j] = val;
            ++val;
        }
        for(;j>0;j--){
            result[i+loop_i][j+loop_j] = val;
            ++val;
        }
        for(;i>0;i--){
            result[i+loop_i][j+loop_j] = val;
            ++val;
        }
        loop_i++;
        loop_j++;
        len = len-2;
    }
    if(n%2==1)result[mid][mid] = n*n;
    return result;
    }
};

额外题目

(以上为训练营每日任务,本部分为自己刷题进度)
题目链接LC 904 水果成篮
思路滑动窗口,本质上是找到长度最大的滑动窗口,并且滑动窗口内的值只能有两个,可以用map保存窗口中数的种类和个数。首先窗口尾指针向后遍历,当种类大于2时开始收缩窗口(窗口首指针向后遍历),直至满足规则,窗口尾指针继续向后遍历,知道数组最后一个之后。
代码

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        int l = 0;//滑动窗口首指针
        int r = 0;//滑动窗口尾指针
        unordered_map<int, int> br;//篮子
        int max = 0;
        while(r<fruits.size()){
            ++br[fruits[r]];//令尾指针的水果入篮子
            while(br.size()>2){//篮子大于两种水果,开始从头指针收缩窗口,同样需要修改map
                auto temp = br.find(fruits[l]);
                --temp->second;//把篮子中的值-1
                if(temp->second == 0) br.erase(temp);
                ++l;
            }
            if(max<r-l+1)max = r-l+1;//保存最大长度
            ++r;//尾指针继续向后遍历
        }
        return max;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值