首页 > 其他分享 >【代码随想录】一、数组:4.滑动窗口

【代码随想录】一、数组:4.滑动窗口

时间:2024-08-15 21:17:39浏览次数:10  
标签:窗口 int res sum 随想录 ++ 数组 滑动

1.题目1:209. 长度最小的子数组

1.1.解法1:暴力解法(已超时)

使用两层循环,外层循环确定最小子数组开始的位置(i),内层循环确定最小子数组结束的位置(j)。在每次跳出内层循环时,sum应重置为0。
当找到的子数组相加的和等于或大于目标值(target)时,算出此刻子数组的长度(j - i + 1),并更新result的值。
最终在外层循环遍历完所有元素时,对result值进行比较,如果result的值没有发生变化,则不存在符合条件的子数组,返回0。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n = nums.size(), res = INT_MAX;
        for (int i = 0; i < n; i++) {
            int sum = 0;
            for (int j = i; j < n; j++) {
                sum += nums[j];
                if (sum >= target) {
                    res = min(res, j - i + 1);
                    break;
                }
            }
        }
        return res == INT_MAX ? 0 : res;
    }
};

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

1.2.解法2:滑动窗口

让i最开始时指向数组起始位置(窗口起始位置),当子数组和大于目标值时,确定窗口的终止位置(j)。将窗口进行缩小,即将i所指位置向前推,相应sum减去i之前元素的值。
举个例子:
nums = [1,1,1,1,100],target = 100。
当j指向100时,开始缩小窗口。i增大,sum减去1、1、1、1。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int res = INT_MAX; 
        int i = 0; // 滑动窗口起始位置
        int sum = 0; // 滑动窗口数值之和
        for (int j = 0; j < nums.size(); j++) {
            sum += nums[j];
            // 每次更新i,比较子序列是否符合要求
            while (sum >= target) {
                res = min(res, j - i + 1); // 取子序列长度
                sum -= nums[i++];
            }
        }
        // 若res没有被赋值,返回0,没有符合条件的子序列
        return res == INT_MAX ? 0 : res;
    }
};

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

2.题目2:904.水果成篮

2.1.解法1:滑动窗口

这题与209的思考过程非常相似,但比较有意思的是使用了unordered_map,它与209中的sum使用方法是类似的。
简述我的思考过程:
据题意,只能保留两个类型的水果,并且需要连续收集尽可能多的水果数量。(即为只出现两个数字且长度最大的连续子数组)。
为了统计当前遍历到的水果类型的数目,使用unordered_map来进行统计:<水果类型,该类型水果数目>,记为unordered_map<int, int>t。
我们设置一个指针j,一直遍历数组,另一个指针i,指向数组的起始位置。
当j遍历时,将水果加入t中,t[fruit[j]]++,fruit[j]为水果类型,t[fruit[j]]为当前统计的该类型水果的数目。
一旦当t.size()大于2时,我们需要将i所指水果减去,更新i所指位置,直至该窗口中仅包含两种类型的水果,j才继续向后遍历。
res始终记录窗口最大长度:res = max(res, j - i + 1)。

在本题中实现滑动窗口,主要确定如下三点:
● 窗口内是什么?
● 如何移动窗口的起始位置?
● 如何移动窗口的结束位置?
窗口就是:只出现两个数字且长度最大的连续子数组。
窗口的起始位置如何移动:如果水果类型(unordered_map中元素)大于2,窗口就要向前移动,使得类型仍为2。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        int res = 0;
        int i = 0;
        unordered_map<int, int>t;
        for (int j = 0; j < fruits.size(); j++) {
            t[fruits[j]]++;
            while (t.size() > 2) {
                auto it = t.find(fruits[i]);
                it->second--;
                if (it->second == 0) t.erase(it);
                i++;
            }
            res = max(res, j - i + 1);
        }
        return res;
    }
};

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

标签:窗口,int,res,sum,随想录,++,数组,滑动
From: https://www.cnblogs.com/Henfiu/p/18359051

相关文章

  • 【代码随想录】一、数组:5.螺旋矩阵
    本题并不涉及到什么算法,就是模拟过程,但却十分考察对代码的掌控能力。1.题目1:59.螺旋矩阵II1.1.解法1:模拟本题的重点还是像之前的“704.二分查找”,坚持循环不变量原则,即在本题中遍历每条边时,坚持相同的原则。如下是一个示例,即n=5,我们考虑根据圈数和边数来进行遍历:由外圈到内......
  • KMP算法——理解 next 数组
    !注意!本文与《王道》,《严书》有所不同,字符串均从第0位开始,next数组没有添加常数1。博客为梳理思路所用,难免纰漏,希望不吝赐教。在字符串匹配中,设m为待匹配的主串S长度,n为找寻的模式串T长度。如:在主串S='ababc'中寻找模式串T='abc'则字符串匹配算法返回S中第......
  • 代码随想录算法训练营 | 动态规划 part01
    509.斐波那契数509.斐波那契数状态转移方程:F(0)=0,F(1)=1F(n)=F(n-1)+F(n-2),其中n>1递归,太多重复计算classSolution{public:intfib(intn){if(n==0||n==1){returnn;}returnfib(n-1)......
  • JS 数组的用法
    一、常用的测试写法//array的写法varmyArray=["Apple","Orange","Banana"];//一、正常循环写法如下:varfruitFinal3=""for(vari=0;i<myArray.length;i++){fruitFinal3+=myArray[i]+""......
  • 代码随想录算法训练营第一天 | 704. 二分查找,27. 移除元素
     704.二分查找题目链接:https://leetcode.cn/problems/binary-search/1,左闭右闭publicintsearch(int[]nums,inttarget){intlow=0;inthigh=nums.length-1;while(low<=high){intmid=(high+low)/2;if(num......
  • JS 对象与数组互相嵌套的复杂例子
    JS写法如下:constmyObj={name:"John",age:30,cars:[{name:"Ford",models:["Fiesta","Focus","Mustang"]},{name:"BMW",models:["32......
  • JavaScript实现数组与树结构的相互转换
    1、将树结构数据转换为数组(按照树结构自上而下的顺序转换)树结构:树结构数据样例:代码转换://将树结构数据转换为数组treeNodes为树结构形式的数据functiontreeToArray(treeNodes){letresult=[];//递归函数traverse,用于处理单个节点functiontraverse(node......
  • 简单的滑动窗口限流接口
    简单的滑动窗口限流接口1.需求我们公司的流程部分使用了好几个版本的流程服务,当前修改为activiti5.5,那么原有的流程部分则进行了停止,但是历史流程部分还是需要提供查询,当前功能只需要流程历史三个月前数据查询使用即可,所以部分代码写死了只处理流程三个月历史信息查询。......
  • 代码随想录算法训练营第43天:动态规划part10:子序列问题
    300.最长递增子序列力扣题目链接(opensnewwindow)给你一个整数数组nums,找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]是数组[0,3,1,6,2,2,7]的子序列。示例1:输入:nums=[10,9,2......
  • 代码随想录day30 || 452 引爆气球,435 无重叠区间,763 划分字母区间
    452射爆气球funcfindMinArrowShots(points[][]int)int{ //思路,尝试按照startasc,endasc排序一下,取交集射爆 iflen(points)==1{ return1 } sort.Slice(points,func(i,jint)bool{ ifpoints[i][0]==points[j][0]{ returnpoints[i][1]<points......