首页 > 编程语言 >(算法)水果成篮——<滑动窗口>

(算法)水果成篮——<滑动窗口>

时间:2024-06-08 11:31:14浏览次数:21  
标签:right hash int ret ++ 算法 滑动 成篮 left

1. 题⽬链接:904.⽔果成篮

2. 题⽬描述:

 

3. 解法(滑动窗⼝): 

算法思路:

研究的对象是⼀段连续的区间,可以使⽤「滑动窗⼝」思想来解决问题。 让滑动窗⼝满⾜:窗⼝内⽔果的种类只有两种。

做法: 

右端⽔果进⼊窗⼝的时候,⽤哈希表统计这个⽔果的频次。这个⽔果进来后,判断哈希表的 ⼤⼩:

▪ 如果⼤⼩超过2:说明窗⼝内⽔果种类超过了两种。那么就从左侧开始依次将⽔果划出窗 ⼝,直到哈希表的⼤⼩⼩于等于2,然后更新结果;

▪ 如果没有超过2,说明当前窗⼝内⽔果的种类不超过两种,直接更新结果ret。

算法流程:  

a. 初始化哈希表hash来统计窗⼝内⽔果的种类和数量; 

b. 初始化变量:左右指针left=0,right=0,记录结果的变量ret=0; 

c. 当right⼩于数组⼤⼩的时候,⼀直执⾏下列循环: 

        i. 将当前⽔果放⼊哈希表中;

        ii. 判断当前⽔果进来后,哈希表的⼤⼩:

                • 如果超过2:

                        ◦ 将左侧元素滑出窗⼝,并且在哈希表中将该元素的频次减⼀;

                        ◦ 如果这个元素的频次减⼀之后变成了0,就把该元素从哈希表中删除;

                        ◦ 重复上述两个过程,直到哈希表中的⼤⼩不超过2;

        iii. 更新结果ret; iv. right++,让下⼀个元素进⼊窗⼝; 

d. 循环结束后,ret存的就是最终结果。

C++算法代码(使⽤容器): 

class Solution
{
public:
	int totalFruit(vector<int>& f)
	{
		unordered_map<int, int> hash; // 统计窗⼝内出现了多少种⽔果 
		int ret = 0;
		for (int left = 0, right = 0; right < f.size(); right++)
		{
			hash[f[right]]++; // 进窗⼝ 
			while (hash.size() > 2) // 判断 
			{
				// 出窗⼝ 
				hash[f[left]]--;
				if (hash[f[left]] == 0)
					hash.erase(f[left]);
				left++;
			}
			ret = max(ret, right - left + 1);
		}
		return ret;
	}
};

C++算法代码(⽤数组模拟哈希表):

class Solution
{
public:
	int totalFruit(vector<int>& f)
	{
		int hash[100001] = { 0 }; // 统计窗⼝内出现了多少种⽔果 
		int ret = 0;
		for (int left = 0, right = 0, kinds = 0; right < f.size(); right++)
		{
			if (hash[f[right]] == 0) kinds++; // 维护⽔果的种类 
			hash[f[right]]++; // 进窗⼝ 
			while (kinds > 2) // 判断 
			{
				// 出窗⼝ 
				hash[f[left]]--;
				if (hash[f[left]] == 0) kinds--;
				left++;
			}
			ret = max(ret, right - left + 1);
		}
		return ret;
	}
};

C++算法代码<使用map>:  

map<char, int>mp;
class Solution
{
public:
    int totalFruit(vector<int>& fruits)
    {
        int count = 0;    //记录水果种类数
        int maxnum = 0; //水果最大数目
        int num = 0;  //记录每个子序列中的水果数目
        map<int, int>mp;
        for (int i = 0; i < fruits.size(); i++)
        {
            mp[fruits[i]] = 0;
        }
        //滑动窗口
        int left = 0, right = 0;
        for (; right < fruits.size(); right++)
        {
            //记录水果种类
            if (mp[fruits[right]] == 0)
            {
                count++;
            }
            mp[fruits[right]]++;
            //进窗口
            if (count <= 2)
            {
                num=right-left+1;
            }
            //退窗口
            while(count > 2)
            {
                maxnum = max(maxnum, num);
                mp[fruits[left]]--;
                //当子序列中水果种类回到2时停止退窗口操作
                if (mp[fruits[left]] == 0)
                {
                    left++;
                    count -= 1;
                    break;
                }
                left++;
            }
            maxnum = max(maxnum, num);
        }
        return maxnum;
    }
};

 Java算法代码(使⽤容器):

class Solution
{
	public int totalFruit(int[] f)
	{
		Map<Integer, Integer> hash = new HashMap<Integer, Integer>(); // 统计窗
		⼝内⽔果的种类
			int ret = 0;
		for (int left = 0, right = 0; right < f.length; right++)
		{
			int in = f[right];
			hash.put(in, hash.getOrDefault(in, 0) + 1); // 进窗⼝ 
			while (hash.size() > 2)
			{
				int out = f[left];
				hash.put(out, hash.get(out) - 1); // 出窗⼝ 
				if (hash.get(out) == 0)
					hash.remove(out);
				left++;
			}
			// 更新结果 
			ret = Math.max(ret, right - left + 1);
		}
		return ret;
	}
}

 Java算法代码(⽤数组模拟哈希表):

class Solution
{
	public int totalFruit(int[] f)
	{
		int n = f.length;
		int[] hash = new int[n + 1]; // 统计窗⼝内⽔果的种类 
		int ret = 0;
		for (int left = 0, right = 0, kinds = 0; right < n; right++)
		{
			int in = f[right];
			if (hash[in] == 0) kinds++; // 维护⽔果种类 
			hash[in]++; // 进窗⼝ 
			while (kinds > 2) // 判断 
			{
				int out = f[left];
				hash[out]--; // 出窗⼝ 
				if (hash[out] == 0) kinds--;
				left++;
			}
			// 更新结果 
			ret = Math.max(ret, right - left + 1);
		}
		return ret;
	}
}

标签:right,hash,int,ret,++,算法,滑动,成篮,left
From: https://blog.csdn.net/2301_79580018/article/details/139544141

相关文章

  • 数据结构学习笔记-迪杰斯特拉算法
    最短路径问题的经典解法-dijsktra算法问题描述:求从一个顶点到另一个顶点的最短路径【算法设计思想】Dijkstra算法的设计思想基于以下关键概念和步骤,旨在找出图中从一个给定的源顶点到其他所有顶点的最短路径。这个算法适用于有向和无向图,只要图的边权重为非负值。1.初始化......
  • Llama模型家族之拒绝抽样(Rejection Sampling)(五)蒙特卡罗算法在拒绝抽样中:均匀分布与
    LlaMA3系列博客基于LlaMA3+LangGraph在windows本地部署大模型(一)基于LlaMA3+LangGraph在windows本地部署大模型(二)基于LlaMA3+LangGraph在windows本地部署大模型(三)基于LlaMA3+LangGraph在windows本地部署大模型(四)基于LlaMA3+LangGraph在w......
  • 【纯干货】深度学习各算法的优缺点和适用场景!建议收藏。(上篇)
    ..纯 干 货.目录前馈神经网络1、梯度下降(GradientDescent)2、随机梯度下降(StochasticGradientDescent,SGD)3、小批量梯度下降(Mini-batchGradientDescent)4、动量(Momentum)5、AdaGrad、RMSprop、Adam等自适应学习率算法卷积神经网络1、LeNet-52、AlexNet3、V......
  • 初级算法01
    用时:42minclassSolution{publicintremoveDuplicates(int[]nums){/***双指针,右指针遍历整个数组,左指针记录有效值*/intl=0,r=0;Set<Integer>s=newHashSet<Integer>();for(;r<nums.l......
  • 覆盖路径规划经典算法 The Boustrophedon Cellular Decomposition 详解
    2000年一篇论文CoverageofKnownSpaces:TheBoustrophedonCellularDecomposition横空出世,解决了很多计算机和机器人领域的覆盖路径问题,今天我来详细解读这个算法。TheBoustrophedonCellularDecomposition算法详解这篇论文标题为"CoveragePathPlanning:TheB......
  • 算法分析与设计实验一、分治策略实现大整数乘法
    目录实验目的和要求实验环境实验内容与过程 实验内容关键代码 流程图实验结果与分析(实验结果截图)结果分析:实验心得实验目的和要求分治策略实现大整数乘法。设计并使时间复杂度为O(n1.59)。实验环境Windows11Pycharm2021实验内容与过程 实验内容对输入的......
  • 【BP时序预测】基于鱼鹰算法OOA优化BP神经网络实现温度数据预测算法研究附matlab代码
    以下是一个大致的步骤和MATLAB代码框架:数据准备:准备用于训练和测试的温度数据集。初始化BP神经网络:定义神经网络的结构(如隐藏层的数量和每层的神经元数量)。定义适应度函数:这是优化算法的目标函数,它应该根据神经网络的预测性能(如均方误差MSE)来评估神经网络的权重和偏置。......
  • 同星TSMaster中如何自定义E2E校验算法
    文章目录前言一、自定义E2E算法教程1.定义checksum算法2.定义【CAN预发送事件】3.E2E报文信号仿真4.运行工程二、TSMaster配置E2E教程1.激活仿真报文2.E2E配置三.小结前言最近因项目需要,用到TSMaster进行E2E校验算法实现。第一次使用TSMaster,把整个的过程做一个记......
  • 代码随想录算法训练营第三十一天 | 455.分发饼干 376.摆动序列 53.最大子数组和
    455.分发饼干题目链接文章讲解视频讲解classSolution{public:intfindContentChildren(vector<int>&g,vector<int>&s){sort(g.begin(),g.end());sort(s.begin(),s.end());intindex=0;//从最小的饼干开始遍历f......
  • 算法学习笔记(23):杜教筛
    杜教筛参考来源:OI-Wiki,网上博客线性筛可以在线性时间求积性函数前缀和,而杜教筛可以用低于线性时间求解积性函数前缀和。我们考虑\(S(n)\)就是积性函数的前缀和,所以我们尝试构造关于\(\largeS(n)\)关于\(\largeS(\lfloor\frac{n}{i}\rfloor)\)的递推式。对于任意......