【算法】滑动窗口解决力扣『水果成篮』问题

🎬 个人主页MSTcheng · CSDN
🌱 代码仓库MSTcheng · Gitee
🔥 精选专栏 : 《C语言
数据结构
《算法学习》
C++由浅入深

💬座右铭: 路虽远行则将至,事虽难做则必成!


前言上一篇文章我们讲解了如何利用滑动窗口来解决,将x减到0的最小操作数问题,本篇文章我们继续使用滑动窗口的思想来解决水果成篮问题。

在前一篇文章中我们介绍了滑动窗口,本篇文章就不再介绍了,直接进入正题:

一、利用滑动窗口解决水果成篮问题

1.1题目展示

1.2题目示例

1.3题目解析

1.4算法原理

从题目中我们看到了最大字眼,以及我们自己总结出来找子数组,那就会想到使用滑动窗口了。

那么优化之后就是典型的滑动窗口的做法了,那么滑动窗口就分为4步:

  1. 进窗口,hash[fruits[right]]++,这一步是将right下标位置的元素插入到哈希表中,并且将次数++
  2. 判断:将right下标位置的数依次插入到哈希表,如果哈希表长度大于2了,说明此时哈希表已经存在三种数了。(这里的哈希表使用的是unordered_map)对于map使用不熟悉的点击: 【C++STL】map / multimap 保姆级教程:从底层原理到实战应用!
  3. 判断完后就要出窗口了,出窗口就需要left++往后缩小窗口,而在++之前一定要确保一种类型的数要彻底被清除比如[1,1,2,2,3,3]right走到第一个3时窗口中含有三种类型的数,此时left++要跳过两个1走到第一个2的时候窗口才合法。 而跳过两个1的方法就是将哈希表里面所存的该数的次数--,人如果减到了0就直接删除。
  4. 更新结果,当窗口满足条件时计算子数组区间的长度即可

1.5代码编写

下面给出完整代码:

cpp 复制代码
class Solution {
public:
    int totalFruit(vector<int>& fruits) 
    {
        int size=fruits.size();
        //定义两个指针
        int left=0,right=0;
        int maxlen=0;
        unordered_map<int,int>  Hash;
        for(right=0;right<size;right++)
        {
            //进入窗口 将fruits[right]位置的数放入哈希表
            Hash.insert({fruits[right],0});
            Hash[fruits[right]]++;
        

            while(Hash.size()>2)
            {
                //出窗口 关心如何将Hash.size()调到等于2的问题
                if(Hash[fruits[left]]!=0)
                    Hash[fruits[left]]--;

                //判断当前的fruits[left]处的果树的个数是否减到0了
                //如果减到0了 就直接删除这种类型的水果
                if(Hash[fruits[left]]==0)
                {
                    auto pos=Hash.find(fruits[left]);
                    Hash.erase(pos);
                }
                left++;//滑出窗口
            }

            //跳出循环此时窗口合法 更新结果
            int currtlen=right-left+1;
            maxlen=max(maxlen,currtlen);
        

        }
        if(maxlen==0)
        {
            //如果maxlen没有更新 那么说明只有一种类型的水果 
            //直接返回数组的大小
            return size;
        }
        return maxlen;
};

三、总结

本题我们使用了滑动窗口来解决,滑动窗口的特征是:

  1. 两个指针都向同一个方向去运动,且指针不会回退。
  2. 滑动窗口的步骤就是:进窗口,判断,出窗口,更新结果这几个步骤。

什么时候该用滑动窗口?

当你看到题目包含以下关键词时,可以考虑:

1、连续(子数组、子串)。

2、求最值(最长、最短、最大和)。

3、约束条件(和等于 K、不包含重复字符)。

相关推荐
LDG_AGI2 小时前
【机器学习】深度学习推荐系统(二十五): X 推荐算法特征系统详解:230+ 特征全解析
人工智能·分布式·深度学习·算法·机器学习·推荐算法
浮鱼浮鱼2 小时前
基于T矩阵的多结构系统的特征模计算
算法·矩阵·天线设计·特征模理论·计算电磁学
清铎2 小时前
leetcode_day14_矩阵_《绝境求生》
算法
很搞笑的在打麻将2 小时前
Java集合线程安全实践:从ArrayList数据迁移问题到synchronizedList解决方案
java·jvm·算法
小小仙。2 小时前
IT自学第十八天
java·开发语言·算法
LDG_AGI2 小时前
【机器学习】深度学习推荐系统(二十八):X 推荐算法listwiseRescoring(同刷多样性降权)机制详解
人工智能·分布式·深度学习·算法·机器学习·推荐算法
Yupureki2 小时前
《算法竞赛从入门到国奖》算法基础:入门篇-贪心算法(上)
c语言·数据结构·c++·算法·贪心算法·visual studio
散峰而望2 小时前
【算法竞赛】队列和 queue
开发语言·数据结构·c++·算法·链表·github·线性回归