代码随想录算法训练营第二天| 977.有序数组的平方、209.长度最小的子数组(904.水果成篮)、59.螺旋矩阵II(54.螺旋矩阵、剑指Offer 29.顺时针打印矩阵)

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

977.有序数组的平方

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

【思路】
昨天刷过了,今天再刷一遍
双指针法,分别指向头start和尾end的位置。比较头和尾的元素j绝对值大小,将大的元素插入进新数组result的尾部。当while(start <= end)结束,返回新数组result。
因为数组不能使用头插法,所以只能创建和原数组一样的大小,从后往前插入元素。

代码:

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int start = 0;
        int end = nums.size() - 1;
        vector<int> result(nums.size());
        int n = nums.size() - 1;
        while(start <= end){
            if(abs(nums[start]) > abs(nums[end])){
                result[n] = nums[start] * nums[start];
                ++start;
                --n;
            }
            else{
                result[n] = nums[end] * nums[end];
                --end;
                --n;
            }
        } 
        return result;
    }
};

时间复杂度:O(n)
空间复杂度:O(n)

209.长度最小的子数组

【题目描述】
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

【思路】
1、暴力解
2、滑动窗口(忘记了

错误暴力解法:

写成了计算子数组个数的解法

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = 0;
        for(int i = 0;i != nums.size() - 1 ;++i){
            int sum = nums[i];
            for(int j = i + 1 ;j != nums.size();++j){
                if(sum + nums[j] < target){
                    sum += nums[j]; 
                }
                else if(sum + nums[j] > target){
                    continue;
                }
                else{
                    ++result;
                }
            }
            if(nums[nums.size() - 1] == target){
                ++result;
            }
        }
        return result;
    }
};

时间复杂度:O(n^2)
空间复杂度:O(1)

暴力解法:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = nums.size();
        int subLenght = 0;
        for(int i = 0;i != nums.size() ;++i){
            int sum = 0;
            for(int j = i  ;j != nums.size();++j){
                sum += nums[j];  //因为都是正整数,所以一直加就好了
                if(sum  >= target){ 
                    subLenght = j - i + 1;
                    result = result > subLenght ? subLenght : result;
                    break; //一找到符合条件就退出当前循环
                }
            }
        }
        return result == nums.size() ? 0 : result; //如果没有修改值就返回0
    }
};

时间复杂度:O(n^2)
空间复杂度:O(1)

滑动窗口解法:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = nums.size() + 1; //取大于nums数组大小的值
        int sum = 0; //滑动窗口大小
        int subLenght = 0; //连续子数组的长度
        int start = 0; //头指针
        for(int end = 0;end != nums.size();++end){ //移动尾指针
            sum += nums[end]; //更新滑动窗口,因为数组中都是正整数,所以可以一直加
            //注意:这里是while循环。当连续子数组的和大于target才进入循环修改result数据
            while(sum >= target){
                subLenght = end - start + 1; //当前连续子数组的长度
                result = result > subLenght ? subLenght : result;//更新最小连续子数组的长度
                sum -= nums[start++];  //缩小滑动窗口的大小,直到小于target才退出循环
            }
        }
        return result == nums.size() + 1 ? 0 : result;//如果最小连续子数组长度没有改变就返回0
    }
};

时间复杂度:O(n)
空间复杂度:O(1)

904.水果成篮

【题目描述】
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。

你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:

你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。

【思路】
不会,思路参考leetcode官方答案
滑动窗口解法:
使用哈希表当做篮子,当使用的篮子个数大于2时,清除start指针所指元素。

滑动窗口解法:

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        unordered_map<int,int> basket; //使用的篮子
        int result = 0; //篮子中水果个数
        int start = 0;
        for(int end = 0;end != fruits.size();++end){
            ++basket[fruits[end]]; //如果哈希表中没有此种类水果,下标操作会直接插入此种类
            while(basket.size() > 2){
                --basket[fruits[start]]; //将哈希表中此种类水果个数减一,直到元素个数为0时,删除此种类
                if(basket[fruits[start]] == 0){
                    basket.erase(fruits[start]);
                }
                ++start;
            }
            result = max(result , end - start + 1); //每次循环都检查当前水果个数是不是比之前多
        }
        return result;
    }
};

时间复杂度:O(n)
空间复杂度:O(1)

59.螺旋矩阵II

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

【思路】
二刷还是不能AC出来
1、设置开始位置(0,0)
2、设置圈数 (忘记)
3、设置偏移量(忘记)
4、设置需要赋值的值
5、判断n是否为奇数,如果是的话在矩阵最中间赋值

代码:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> result(n,vector<int>(n)); //最终的正方形矩阵
        int startX = 0,startY = 0; //循环起始位置(0,0)
        int num = 1; //要赋值的数
        int count = n / 2; //循环总圈数
        int offset = 1; //每一圈的偏移量


        while(count > 0){
            for(;startX < n - offset ; ++startX){
                result[startY][startX] = num++; 
                
            }

            for(;startY < n - offset;++startY){
                result[startY][startX] = num++;
                
            }

            for(;startX > offset - 1;--startX){
                result[startY][startX] = num++;
                
            }

            for(;startY > offset - 1;--startY){
                result[startY][startX] = num++;
                
            }

            ++startX;
            ++startY;
            ++offset;
            --count;
        }
        if(n % 2 != 0){  //如果n为奇数的话,为最中间的位置赋值
            result[n/2][n/2] = num;
        }

        return result;
    }
};

时间复杂度:O(n^2)
空间复杂度:O(1)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值