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

🎬 个人主页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、不包含重复字符)。

相关推荐
田梓燊13 小时前
2026/4/11 leetcode 3741
数据结构·算法·leetcode
斯内科13 小时前
FFT快速傅里叶变换
算法·fft
2301_8227032013 小时前
开源鸿蒙跨平台Flutter开发:幼儿疫苗全生命周期追踪系统:基于 Flutter 的免疫接种档案与状态机设计
算法·flutter·华为·开源·harmonyos·鸿蒙
贵慜_Derek13 小时前
Managed Agents 里,Harness 到底升级了什么?
人工智能·算法·架构
2301_8227032014 小时前
鸿蒙flutter三方库实战——教育与学习平台:Flutter Markdown
学习·算法·flutter·华为·harmonyos·鸿蒙
Jia ming14 小时前
C语言实现日期天数计算
c语言·开发语言·算法
无限进步_14 小时前
【C++&string】大数相乘算法详解:从字符串加法到乘法实现
java·开发语言·c++·git·算法·github·visual studio
苏纪云15 小时前
蓝桥杯考前突击
c++·算法·蓝桥杯
W230357657315 小时前
经典算法详解:最长公共子序列 (LCS) —— 从暴力递归到动态规划完整实现
算法·动态规划·最长子序列
pzx_00115 小时前
【优化器】 随机梯度下降 SGD 详解
人工智能·python·算法