算法题 水果成篮

水果成篮

问题描述

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

你有两个篮子,每个篮子只能装单一类型的水果,但你可以选择任意两棵树开始收集水果。

你必须从每棵树(包括选择的起始树)连续地收集水果,一旦遇到第三种类型的水果,就必须停止。

返回你能收集的水果的最大数目

示例

输入:fruits=[1,2,1]输出:3解释:可以收集[1,2,1]输入:fruits=[0,1,2,2]输出:3解释:可以收集[1,2,2]输入:fruits=[1,2,3,2,2]输出:4解释:可以收集[2,3,2,2]输入:fruits=[3,3,3,1,2,1,1,2,3,3,4]输出:5解释:可以收集[1,2,1,1,2]

算法思路

滑动窗口 + 哈希表

  1. 问题转化

    • 找到最长的连续子数组,其中最多包含两种不同的元素
    • 这是一个经典的滑动窗口问题
  2. 滑动窗口策略

    • 右指针right:扩展窗口,将新水果加入篮子
    • 左指针left:当篮子中水果种类超过2种时,收缩窗口
    • 哈希表:记录当前窗口中每种水果的出现次数
  3. 窗口收缩条件

    • 当哈希表的大小 > 2 时,需要收缩左边界
    • 移除fruits[left],如果其计数变为0,从哈希表中删除
    • left++继续收缩,直到哈希表大小 ≤ 2
  4. 最大长度更新

    • 每次扩展右边界后,如果窗口有效(水果种类 ≤ 2),更新最大长度
    • 最大长度 =right - left + 1

代码实现

方法一:滑动窗口 + 哈希表

importjava.util.*;classSolution{/** * 水果成篮 - 滑动窗口 * * @param fruits 水果类型数组 * @return 能收集的最大水果数目 * * 算法思路: * 1. 使用滑动窗口维护最多包含2种水果的连续子数组 * 2. 哈希表记录当前窗口中每种水果的计数 * 3. 当水果种类超过2种时,收缩左边界 */publicinttotalFruit(int[]fruits){Map<Integer,Integer>fruitCount=newHashMap<>();intleft=0;intmaxFruits=0;// 右指针扩展窗口for(intright=0;right<fruits.length;right++){// 将当前水果加入窗口fruitCount.put(fruits[right],fruitCount.getOrDefault(fruits[right],0)+1);// 当水果种类超过2种时,收缩左边界while(fruitCount.size()>2){intleftFruit=fruits[left];fruitCount.put(leftFruit,fruitCount.get(leftFruit)-1);// 如果某种水果计数为0,从哈希表中移除if(fruitCount.get(leftFruit)==0){fruitCount.remove(leftFruit);}left++;}// 更新最大水果数目maxFruits=Math.max(maxFruits,right-left+1);}returnmaxFruits;}}

算法分析

  • 时间复杂度:O(n)

    • 每个元素最多被访问两次(右指针和左指针各一次)
    • 哈希表操作为 O(1)
  • 空间复杂度:O(1)

    • 哈希表最多存储3个键值对(收缩前)

算法过程

1:fruits = [1,2,1]

滑动窗口过程

初始: left=0, maxFruits=0, fruitCount={} right=0: fruits[0]=1 - fruitCount={1:1} - maxFruits = max(0, 0-0+1) = 1 right=1: fruits[1]=2 - fruitCount={1:1, 2:1} - maxFruits = max(1, 1-0+1) = 2 right=2: fruits[2]=1 - fruitCount={1:2, 2:1} - maxFruits = max(2, 2-0+1) = 3 返回 3

2:fruits = [3,3,3,1,2,1,1,2,3,3,4]

窗口扩展到 [3,3,3,1] → 种类=2,长度=4 继续扩展到 [3,3,3,1,2] → 种类=3,需要收缩 收缩过程: - 移除fruits[0]=3 → {3:2, 1:1, 2:1} - 移除fruits[1]=3 → {3:1, 1:1, 2:1} - 移除fruits[2]=3 → {1:1, 2:1},left=3 窗口变为 [1,2],继续扩展... 最终找到 [1,2,1,1,2],长度=5

3:fruits = [1,2,3,2,2]

[1] → len=1 [1,2] → len=2 [1,2,3] → 种类=3,收缩到 [2,3] → len=2 [2,3,2] → len=3 [2,3,2,2] → len=4 最大长度=4

测试用例

importjava.util.*;publicclassTest{publicstaticvoidmain(String[]args){Solutionsolution=newSolution();// 测试用例1:标准示例int[]fruits1={1,2,1};System.out.println("Test 1: "+solution.totalFruit(fruits1));// 3// 测试用例2:需要收缩窗口int[]fruits2={0,1,2,2};System.out.println("Test 2: "+solution.totalFruit(fruits2));// 3// 测试用例3:中间有最长序列int[]fruits3={1,2,3,2,2};System.out.println("Test 3: "+solution.totalFruit(fruits3));// 4// 测试用例4:复杂情况int[]fruits4={3,3,3,1,2,1,1,2,3,3,4};System.out.println("Test 4: "+solution.totalFruit(fruits4));// 5// 测试用例5:所有相同int[]fruits5={1,1,1,1,1};System.out.println("Test 5: "+solution.totalFruit(fruits5));// 5// 测试用例6:两种交替int[]fruits6={1,2,1,2,1,2};System.out.println("Test 6: "+solution.totalFruit(fruits6));// 6// 测试用例7:单个元素int[]fruits7={1};System.out.println("Test 7: "+solution.totalFruit(fruits7));// 1// 测试用例8:两个元素int[]fruits8={1,2};System.out.println("Test 8: "+solution.totalFruit(fruits8));// 2// 测试用例9:三种连续int[]fruits9={1,2,3};System.out.println("Test 9: "+solution.totalFruit(fruits9));// 2// 测试用例10:大数组int[]fruits10=newint[40000];Arrays.fill(fruits10,1);fruits10[20000]=2;fruits10[30000]=3;System.out.println("Test 10: "+solution.totalFruit(fruits10));// 20001// 测试用例11:边界值int[]fruits11={0,1,0,1,0,1,0,1,0,1,2};System.out.println("Test 11: "+solution.totalFruit(fruits11));// 10// 测试用例12:从后往前的最长序列int[]fruits12={1,2,1,1,2,2,2,2,2};System.out.println("Test 12: "+solution.totalFruit(fruits12));// 9}}

关键点

  1. 滑动窗口

    • 右指针不断扩展,左指针在必要时收缩
    • 保证窗口内最多包含2种水果
  2. 哈希表

    • 记录当前窗口中每种水果的数量
    • 通过大小判断是否超过2种
    • 通过计数为0时移除键来准确维护种类数
  3. 边界条件处理

    • 数组长度 ≤ 2 时直接返回长度
    • 空数组

常见问题

  1. 为什么不用Set而用Map?

    • Set只能记录种类,无法记录每种水果的数量
    • 需要知道何时可以安全移除某种水果(计数为0时)
  2. 如果篮子数量不是2而是k?

    • 算法逻辑相同,只需要将条件> 2改为> k
    • 这是滑动窗口解决"最多k种元素"问题的通用模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1131144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

零成本体验:免费GPU资源+预装镜像玩转AI绘画

零成本体验&#xff1a;免费GPU资源预装镜像玩转AI绘画 作为一名对AI绘画感兴趣的大学生&#xff0c;你是否曾因高昂的GPU云服务费用和复杂的本地部署流程而望而却步&#xff1f;本文将介绍如何利用免费GPU资源和预装镜像&#xff0c;零门槛体验Stable Diffusion等AI绘画技术&a…

科哥手把手教学:1小时掌握Z-Image-Turbo二次开发

科哥手把手教学&#xff1a;1小时掌握Z-Image-Turbo二次开发 作为一名全栈开发者&#xff0c;当我接到集成Z-Image-Turbo的任务时&#xff0c;内心是有些忐忑的。虽然我对传统开发流程轻车熟路&#xff0c;但AI模型开发领域对我来说还是一片未知的领域。幸运的是&#xff0c;经…

技术创业者必看:低成本搭建AI图像生成SaaS

技术创业者必看&#xff1a;低成本搭建AI图像生成SaaS 为什么选择AI图像生成SaaS&#xff1f; 作为一名技术创业者&#xff0c;你可能已经注意到AI图像生成技术的巨大潜力。从营销海报到产品设计&#xff0c;Stable Diffusion等开源模型正在改变内容创作的方式。但传统部署方案…

API开发速成:基于预配置Z-Image-Turbo环境快速构建图像生成服务

API开发速成&#xff1a;基于预配置Z-Image-Turbo环境快速构建图像生成服务 作为一名后端工程师&#xff0c;当你接到任务要将Z-Image-Turbo集成到公司系统时&#xff0c;可能会对AI模型部署感到陌生。本文将介绍如何利用预配置的Z-Image-Turbo环境快速构建图像生成API服务&…

等保二级与三级深度解析及对比分析

在数字化时代,网络安全等级保护制度已成为企业保障信息安全的重要合规手段。等保二级和三级作为常见的保护级别,在适用场景、技术要求和管理措施等方面存在显著差异。本文将对等保二级和三级进行详细解析,并对比分析两者的核心差异,为企业选择合适的等保级别提供参考。 一…

产品经理必备:10分钟了解AI图像生成技术

产品经理必备&#xff1a;10分钟了解AI图像生成技术 作为一名非技术背景的产品经理&#xff0c;你可能经常听到"Stable Diffusion"、"AI绘图"这些热词&#xff0c;但面对复杂的安装配置和GPU需求&#xff0c;往往无从下手。本文将带你快速理解AI图像生成的…

亲测好用!9款AI论文软件测评:本科生毕业论文全攻略

亲测好用&#xff01;9款AI论文软件测评&#xff1a;本科生毕业论文全攻略 AI论文软件测评&#xff1a;为什么你需要一份靠谱的工具推荐 随着人工智能技术的不断进步&#xff0c;越来越多的本科生开始借助AI工具辅助毕业论文写作。然而&#xff0c;面对市场上琳琅满目的AI论文软…

揭秘Z-Image-Turbo超快推理:预配置镜像+云端GPU实战指南

揭秘Z-Image-Turbo超快推理&#xff1a;预配置镜像云端GPU实战指南 如果你正在寻找一种能够快速生成高质量图像的AI解决方案&#xff0c;Z-Image-Turbo绝对值得关注。这款由阿里巴巴通义MAI团队开发的图像生成模型&#xff0c;通过创新的8步蒸馏技术&#xff0c;在保持照片级质…

STM32嵌入式:如何使用VSCode EIDE来获取flash块数据并转换成可视化的数据 来判断源头数据是否错误

STM32嵌入式&#xff1a;如何使用VSCode EIDE来获取flash块数据并转换成可视化的数据 来判断源头数据是否错误 VSCode 里 EIDE 本身没有像 Keil 那样“直接导出 Flash 到文件”的按钮。但你已经在用 EIDE Cortex-Debug 调试&#xff0c;所以可以用调试后端&#xff08;OpenOCD…

算法题 最小差值 I

908. 最小差值 I 问题描述 给你一个整数数组 nums 和一个整数 k。你可以选择数组中的任一元素并将其替换为 [num - k, num k] 范围内的任意整数。 在应用此操作至多一次后&#xff0c;求数组中最大值和最小值之间的最小可能差值。 示例&#xff1a; 输入: nums [1], k 0 输出…

告别CUDA报错:预装镜像带你轻松玩转Z-Image-Turbo

告别CUDA报错&#xff1a;预装镜像带你轻松玩转Z-Image-Turbo 作为一名计算机专业的学生&#xff0c;在课程项目中需要使用AI生成图像时&#xff0c;你是否曾被各种依赖包冲突和CUDA版本问题困扰得焦头烂额&#xff1f;本文将介绍如何通过预装好的Z-Image-Turbo镜像&#xff0c…

玩转AI绘画:周末用云端GPU打造个人艺术展

玩转AI绘画&#xff1a;周末用云端GPU打造个人艺术展 作为一名艺术爱好者&#xff0c;你是否曾想过举办一场属于自己的AI艺术展&#xff1f;借助Stable Diffusion等开源AI绘画工具&#xff0c;现在完全可以在云端GPU环境下快速生成高质量的艺术作品。本文将手把手教你如何利用预…

简析:一种名为 ObjectSense 的编程语言

让我们通过以下三个维度来了解它&#xff1a;1. 语言本质与起源 基础平台&#xff1a;它是一种基于 Vim Script (VimL) 进行面向对象封装的脚本编程语言。核心特性&#xff1a;高度精炼&#xff0c;核心代码仅在千行之内。设计初衷&#xff1a;旨在让开发者能像写 Python 一样简…

使用MATLAB绘制3D心形图和玫瑰花图案

以下是两种不同的实现方法&#xff1a; 1. 3D心形图 方法一&#xff1a;参数方程心形 % 3D心形图 - 参数方程方法 figure(Position, [100, 100, 1200, 500]);% 子图1&#xff1a;参数方程心形 subplot(1,2,1); % 创建网格 [u, v] meshgrid(linspace(0, 2*pi, 50), linspace(0,…

贴吧引流项目,积攒收录被动引流,可以自己搭配脚本操作

贴吧被动引流教程&#xff0c;长期积攒百度收录被动流量聪明的同学可以自己去定制脚本&#xff0c;让脚本帮你操作。

Z-Image-Turbo模型调优实战:免环境配置的云端实验平台

Z-Image-Turbo模型调优实战&#xff1a;免环境配置的云端实验平台 如果你是一名AI工程师&#xff0c;想要对Z-Image-Turbo进行微调实验&#xff0c;但每次尝试新参数都要处理环境问题&#xff0c;那么这篇文章正是为你准备的。Z-Image-Turbo是阿里巴巴通义实验室推出的6B参数图…

AsterNOS SONiC基于YANG模型的现代网络管理:从CLI到gNMI的演进

从“运维之困”到“模型驱动”&#xff1a;新一代网络管理的必然演进 对于许多网络运维工程师而言&#xff0c;这样的一幕或许并不陌生&#xff1a;面对成百上千台多厂商设备&#xff0c;一边在命令行中重复着繁琐的配置脚本&#xff0c;一边在监控屏幕上审视着分钟级延迟的流…

边缘计算整合:如何用云端Z-Image-Turbo环境开发混合AI绘画应用

边缘计算整合&#xff1a;如何用云端Z-Image-Turbo环境开发混合AI绘画应用 在当今AI技术快速发展的背景下&#xff0c;将云端AI能力与边缘设备相结合的混合架构正成为创新应用的热门选择。本文将详细介绍如何使用Z-Image-Turbo这一高效的AI绘画模型&#xff0c;在云端GPU环境中…

状态监测及群智能散货港口运行优化【附代码】

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅成品或者定制&#xff0c;扫描文章底部微信二维码。(1) 港口状态监测数据集成系统与卸车调度优化方法散货港口作为大宗货物转运的关键节点…

AI生成社交媒体素材:营销团队的效率革命

AI生成社交媒体素材&#xff1a;营销团队的效率革命 社交媒体运营团队每天面临的最大挑战之一&#xff0c;就是需要持续产出高质量的视觉内容。传统设计流程耗时费力&#xff0c;而AI工具的出现正在改变这一局面。本文将介绍如何利用Stable Diffusion等开源模型快速生成可商用的…