LeetCood算法題~水果成籃

水果成籃

你正在探訪一家農場,農場從左到右種植了一排果樹。這些樹用一個整數數組 fruits 表示,其中 fruits[i] 是第 i 棵樹上的水果 種類 。
你想要盡可能多地收集水果。然而,農場的主人設定了一些嚴格的規矩,你必須按照要求采摘水果:
你只有 兩個 籃子,并且每個籃子只能裝 單一類型 的水果。每個籃子能夠裝的水果總量沒有限制。
你可以選擇任意一棵樹開始采摘,你必須從 每棵 樹(包括開始采摘的樹)上 恰好摘一個水果 。采摘的水果應當符合籃子中的水果類型。每采摘一次,你將會向右移動到下一棵樹,并繼續采摘。 一旦你走到某棵樹前,但水果不符合籃子的水果類型,那么就必須停止采摘。 給你一個整數數組 fruits ,返回你可以收集的水果的 最大 數目。
示例 1:
輸入:fruits = [1,2,1]
輸出:3
解釋:可以采摘全部 3 棵樹。
示例 2:
輸入:fruits = [0,1,2,2]
輸出:3
解釋:可以采摘 [1,2,2] 這三棵樹。
如果從第一棵樹開始采摘,則只能采摘 [0,1] 這兩棵樹。
示例 3:
輸入:fruits = [1,2,3,2,2]
輸出:4
解釋:可以采摘 [2,3,2,2] 這四棵樹。
如果從第一棵樹開始采摘,則只能采摘 [1,2] 這兩棵樹。
示例 4:
輸入:fruits = [3,3,3,1,2,1,1,2,3,3,4]
輸出:5
解釋:可以采摘 [1,2,1,1,2] 這五棵樹。
提示:
1 <= fruits.length <= 105
0 <= fruits[i] < fruits.length

解題思路:

1. 使用兩個指針left和right表示窗口的左右邊界,初始時都指向數組的起始位置。
2. 使用一個哈希表(或者數組,因為題目說明fruits[i]的范圍,但為了通用性,這里用哈希表)來記錄當前窗口內各種水果的出現次數。
3. 右指針right不斷向右移動,將遇到的水果加入窗口(即更新哈希表)。
4. 當窗口內水果種類超過2種時,移動左指針left,直到窗口內水果種類減少到2種(每次移動左指針,將左指針指向的水果從哈希表中移除,如果該水果數量減為0,則從哈希表中刪除該種類)。
5. 在移動過程中,記錄窗口的最大長度(即right-left+1),并更新最大長度。

具體步驟

初始化left=0, maxLen=0

使用一個HashMap來記錄當前窗口內每種水果的出現次數,也可以使用數組(因為fruits[i] < fruits.length,所以數組長度可以設為fruits.length,但為了通用,這里用HashMap)

遍歷right從0到len-1:
將fruits[right]加入HashMap(計數+1)
當HashMap的大小(即不同水果的種類)超過2時,開始移動左指針:
將fruits[left]從HashMap中移除(計數-1,如果減到0,則刪除該鍵)
left++
此時窗口內的水果種類不超過2,更新最大長度:maxLen = max(maxLen, right-left+1)
但是,注意:在移動左指針的過程中,我們只需要移除直到窗口內水果種類重新變為2即可。因此,在移動左指針時,使用while循環直到HashMap大小<=2。

然而,實際上,由于每次只增加一個元素,因此當種類超過2時,我們只需要移動一次左指針(但是注意,可能一次移動并不夠,因為可能移除了一個水果后,窗口內仍然有兩種以上?實際上,由于我們每次移除一個,所以當種類超過2時,我們一直移動左指針直到種類等于2)。因此,內層使用while循環。

優化:由于我們使用HashMap記錄每個水果出現的次數,當移除left位置的水果時,如果該水果在窗口內出現的次數減到0,那么我們就從HashMap中移除這個鍵,這樣HashMap的大小就是當前窗口內的水果種類數。

代碼實現

 public static int totalFruit(int[] fruits) {int n = fruits.length;// 頻率數組:記錄當前窗口中每種水果出現的次數// 數組大小設為n,因為水果種類范圍是[0, n)int[] freq = new int[n];// 左指針:標記窗口起始位置int left = 0;// 最大長度:記錄滿足條件的最大窗口長度int maxLen = 0;// 種類計數:記錄當前窗口中的水果種類數int count = 0;// 右指針遍歷整個數組for (int right = 0; right < n; right++) {// 如果當前水果在窗口中首次出現,增加種類計數if (freq[fruits[right]] == 0) {count++;}// 增加當前水果的頻率計數freq[fruits[right]]++;// 當窗口中水果種類超過2種時,需要縮小窗口while (count > 2) {// 減少左指針指向的水果的頻率計數freq[fruits[left]]--;// 如果某種水果頻率降為0,減少種類計數if (freq[fruits[left]] == 0) {count--;}// 左指針右移,縮小窗口left++;}// 更新最大窗口長度maxLen = Math.max(maxLen, right - left + 1);}return maxLen;}

代碼解析: 初始化數據結構:

freq 數組:記錄當前窗口中每種水果出現的次數(索引對應水果種類)

left 指針:標記滑動窗口的起始位置

maxLen:記錄滿足條件的最長子數組長度

count:記錄當前窗口中的水果種類數

滑動窗口處理:

右指針擴展:right 指針從左到右遍歷數組

新種類檢測:當遇到窗口中未出現的水果種類時,增加種類計數 count

頻率更新:增加當前水果在頻率數組中的計數

窗口收縮:當種類數超過2時,移動左指針縮小窗口:

減少左指針指向水果的頻率計數

如果某種水果頻率降為0,減少種類計數

左指針右移

更新最大長度:每次循環后計算當前窗口長度并更新最大值

算法特性:

時間復雜度:O(n) - 每個元素最多被訪問兩次(右指針和左指針各一次)

空間復雜度:O(n) - 使用頻率數組存儲計數信息

最優性:滑動窗口確保在單次遍歷中高效找到最優解

算法原理:
該問題本質是尋找最多包含兩種不同元素的最長連續子數組。滑動窗口技術通過以下步驟解決:

窗口擴展:右指針不斷向右移動,擴展窗口范圍

狀態維護:使用頻率數組實時跟蹤窗口內各元素數量

種類控制:當窗口內元素種類超過2時,左指針向右移動收縮窗口

結果更新:每次窗口調整后,記錄滿足條件的最大窗口長度

這種方法保證了在O(n)時間內找到最優解,尤其適合處理大規模數據(題目中數組長度可達10^5),是解決此類問題的最優方案。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/92049.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/92049.shtml
英文地址,請注明出處:http://en.pswp.cn/web/92049.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Lua】題目小練8

-- 題目 1&#xff1a;定義一個類 Person-- 屬性&#xff1a;name、age&#xff0c;其中 age 默認是 0&#xff0c;不能小于 0。-- 方法&#xff1a;introduce()&#xff0c;輸出 "My name is <name>, I am <age> years old."-- 要求使用封裝思想&#x…

SAP PP CK466

原因 作業價格沒有維護 解決方案 KP26

如何解決pip安裝報錯ModuleNotFoundError: No module named ‘keras’問題

【Python系列Bug修復PyCharm控制臺pip install報錯】如何解決pip安裝報錯ModuleNotFoundError: No module named ‘keras’問題 摘要 在使用 PyCharm 進行深度學習項目開發時&#xff0c;常常需要通過 pip install keras 來安裝 Keras 庫。但有時即便命令執行成功&#xff0c…

人工智能領域、圖歐科技、IMYAI智能助手2024年全年歷史更新大事件匯總

2024年 2024年12月29日 【通知】 1、主站導出文檔功能優化升級&#xff0c;新增支持了純文本WORD導出功能&#xff0c;支持使用WPS軟件打開 注&#xff1a;原來的富文本WORD不支持使用WPS打開&#xff0c;只支持系統自帶的WORD軟件打開&#xff0c;比如Microsoft Office Word 2…

UWB實操:使用UCI CMD測距;UCI CMD是一串數字,創建測距session,配置測距session,開始測距session。

使用UCI CMD測距; UCI CMD是一串數字,創建測距session,配置測距session,開始測距session。根據 FiRa_UCI_Technical_Specification,我們可以分析并組織測距cmd 例如: Fira2.0 1v1 發起 DSTWR 創建測距session:210000052222222200 配置測距session: 2103001F222…

從AUTOSAR角度理解CAN以及CANFD

一、AUTOSAR對CAN和CAN FD的基礎定位 CAN&#xff1a;基于傳統CAN 2.0B協議&#xff0c;是AUTOSAR早期版本&#xff08;如4.0.3及之前&#xff09;的核心車載通信協議&#xff0c;支持最大8字節 payload&#xff0c;仲裁段波特率通常≤1Mbps&#xff0c;適用于低帶寬、高實時性…

第27章:服務部署與容器化

1. 課程引言 在前面的章節中&#xff0c;我們已經完成了電商項目核心服務的開發。然而&#xff0c;開發完成只是項目生命周期的一部分&#xff0c;如何將這些服務高效、可靠地部署到生產環境&#xff0c;是決定項目成敗的關鍵一步。本章將聚焦于服務的部署&#xff0c;重點介紹…

力扣148:排序鏈表

力扣148:排序鏈表題目思路代碼題目 給你鏈表的頭結點 head &#xff0c;請將其按 升序 排列并返回 排序后的鏈表 。 思路 當我們第一眼看見這道題時心中其實是有思路的&#xff0c;我們不想這是個鏈表就當它是一個整型數組。那么自然而然就會想到各種各樣的排序方法&#xf…

基于k8s環境下的pulsar常用命令(下)

#作者&#xff1a;Unstopabler 文章目錄permissionSchemapermission pulsar的權限控制是在namespace級別的 kubectl exec pulsar-toolset-0 -n pulsar – bin/pulsar-admin namespaces grant-permission mytenant/mynamespace –actions produce,consume –role admin10 注…

2.4 組件通信

Props 和 Events&#xff08;父子組件通信&#xff09;Props&#xff1a;父組件向子組件傳遞數據使用 props。子組件通過聲明 props 來接收來自父組件的數據。<!-- 父組件 --> <template><ChildComponent :message"parentMessage" /> </templat…

PCL學習之路-基礎知識-(一)

文章目錄1.西門子S7系列PLC類型劃分(1).大型PLC&#xff1a;S7-400(2).中型PLC&#xff1a;S7-300(3).小型PLC&#xff1a;S7-200系列2.西門子S7外形結構(1).總覽&#xff1a;PLC的“器官”分工邏輯3.輸出電路(1).小型繼電器輸出形式(2).大功率晶體管/場效應管輸出形式(3).雙向…

leetcode654:最大二叉樹(遞歸與單調棧雙解法)

文章目錄一、 題目描述二、 核心思路&#xff1a;分而治之與遞歸構造三、代碼實現與深度解析四、 關鍵點與復雜度分析五、拓展解法單調棧解法兩種解法對比LeetCode 654. 最大二叉樹&#xff0c;【難度&#xff1a;中等&#xff1b;通過率&#xff1a;82.6%】&#xff0c;這道題…

Python 循環語法詳解

在編程中&#xff0c;循環是一種非常常見的控制結構。很多時候&#xff0c;我們需要重復做一些事情&#xff0c;比如遍歷列表、處理數據、嘗試直到成功等。這時候&#xff0c;就離不開循環了。Python 提供了兩種主要的循環結構&#xff1a;for 循環 和 while 循環。本篇文章會從…

一個小巧神奇的 USB數據線檢測儀

一個小巧的數據線檢測儀&#xff0c;檢測各種USB數據線是否損壞、通斷&#xff0c;TYPE_C、MICRO_B、蘋果線、燒錄線、網線都可檢測。嵌入式開發者的稱手工具。 這個是我個人制作的&#xff0c;SMT和連接器比較貴&#xff0c;特別是24PIN的C口連接器&#xff0c;我掛在黃色小魚…

37.【.NET8 實戰--孢子記賬--從單體到微服務--轉向微服務】--擴展功能--增加Github Action

在第二部分&#xff08;微服務基礎工具與技術&#xff09;中我們講解了GitHub Action的相關知識&#xff0c;那么在這一節中&#xff0c;我們將為已有的微服務增加GitHub Action的支持。 一、什么是GitHub Action 雖然前面已經介紹過GitHub Action的相關知識&#xff0c;但這里…

ROS2 通過 命令行 發布速度控制指令 控制 麥克娜姆輪

在 ROS2 中&#xff0c;要通過命令行發布速度控制指令來控制麥克娜姆輪機器人&#xff0c;你需要知道機器人所使用的速度控制話題和消息類型。通常麥克娜姆輪機器人使用geometry_msgs/Twist消息類型來接收速度指令。 以下是通過命令行發布速度控制指令的方法&#xff1a; 首先確…

多層Model更新多層ListView

一、總體架構QML (三層 ListView)└─ C 單例 DataCenter (QQmlContext 注冊)├─ L1Model (一級節點)│ └─ 內部持有 QList<L2Model*>│ └─ L2Model (二級節點)│ └─ 內部持有 QList<L3Model*>│ └─ L3Model (三級節…

Git基礎操作教程

本文目的是掌握Git基礎操作教程一、Git簡介Git&#xff1a;分布式版本控制系統&#xff0c;使用倉庫(Repository)來記錄文件的變化最流行的版本控制系統有兩種&#xff1a;集中式&#xff08;SVN&#xff09;、分布式&#xff08;Git&#xff09;二、Git操作1.創建倉庫倉庫(Rep…

Android 之 Kotlin

變量變量的聲明Kotlin使用var&#xff0c;val來聲明變量&#xff0c;注意&#xff1a;Kotlin不再需要;來結尾var 可變變量&#xff0c;對應java的非final變量var b 1val不可變變量&#xff0c;對應java的final變量val a 1兩種變量并未聲明類型&#xff0c;這是因為Kotlin存在…

Design Compiler:布圖規劃探索(ICC)

相關閱讀 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 簡介 在Design Compiler Graphical中&#xff0c;可以用布圖規劃探索(Floorplan Exploration)功能&#xff0c;打開IC Compiler進行布圖規劃的創建、修改與分…