【LeetCode904. 水果成籃】——滑動窗口、哈希表

904. 水果成籃

你正在探訪一家農(nóng)場,農(nóng)場從左到右種植了一排果樹。這些樹用一個整數(shù)數(shù)組 fruits 表示,其中 fruits[i] 是第 i 棵樹上的水果 種類 。

你想要盡可能多地收集水果。然而,農(nóng)場的主人設定了一些嚴格的規(guī)矩,你必須按照要求采摘水果:

  • 你只有 兩個 籃子,并且每個籃子只能裝 單一類型 的水果。每個籃子能夠裝的水果總量沒有限制。
  • 你可以選擇任意一棵樹開始采摘,你必須從 每棵 樹(包括開始采摘的樹)上 恰好摘一個水果 。采摘的水果應當符合籃子中的水果類型。每采摘一次,你將會向右移動到下一棵樹,并繼續(xù)采摘。
  • 一旦你走到某棵樹前,但水果不符合籃子的水果類型,那么就必須停止采摘。

給你一個整數(shù)數(shù)組 fruits ,返回你可以收集的水果的 最大 數(shù)目。
題目鏈接:https://leetcode.cn/problems/fruit-into-baskets

示例 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

思路:

首先這道題理解起來就較有難度,數(shù)組中的數(shù)表示的是水果的種類,即每一個數(shù)字都代表一種水果。我一開始傻傻的理解為是樹上水果種類的個數(shù),看了示例才明白過來。

在理解問題的基礎上,可以發(fā)現(xiàn),這也是一道尋找最長子序列的問題,這次的限制條件就是,子序列中最多含有兩種類型的水果,即兩種數(shù)。

滑動窗口+哈希表:

因為這道題目又涉及到了求最長或最短子序列的問題,所以自然而然我們也可以使用滑動窗口的方法進行求解。而本題的另一個難點就在于,如何讓窗口進行變動,縮小窗口。題目中的限制條件就是,所拿的水果種類不能夠超過兩種,所以我們有必要記錄目前所含有的水果種類。針對這個問題,哈希表是非常適合的。

class Solution {
public:
    //滑動窗口
    int totalFruit(vector<int>& fruits) {
        int ans[100000] = { 0 };//簡易哈希表,并初始化,用于記錄不同種類水果的個數(shù)
        int result = 0; //讓result取0(因為要求的是最大值)
        int sum = 0; // 數(shù)組中已有水果的種類
        int i = 0; // 滑動窗口起始位置
        int subLength = 0; // 滑動窗口的長度

        for (int j = 0; j < fruits.size(); j++) { //j指向滑動窗口的末尾位置,用來遍歷
            if (ans[fruits[j]] == 0) //若該種類水果的個數(shù)為0
            {
                sum++;//添加新水果,水果種類增加
            }
            ans[fruits[j]]++;//該種水果數(shù)量加一
            while (sum > 2) //當水果的種類大于2時,要進行刪除一類水果的操作
            {
                ans[fruits[i]]--; //刪除當前種類的水果 
                if (ans[fruits[i]] == 0)//收縮至有一種水果個數(shù)為0
                {
                    sum--;//水果種類減少
                }
                i++;//刪除水果的過程即縮小窗口大小的過程
            }
            subLength = j - i + 1;
            result = result > subLength ? result : subLength;
        }

        return result;
    }
};

哈希表的實現(xiàn)方式有三種:數(shù)組、set、map。這里由于題目中提示已告訴我們,水果的種類不超過10000種,所以我們可以建立一個大小為10000的數(shù)組,并初始化所有值為零,從而建立一個哈希表。

而剩下的部分,則為常規(guī)的滑動窗口問題,用兩個指針進行遍歷,不斷調(diào)整窗口的大小,最終尋找到符合條件的值。

往期回顧:
LeetCode977.有序數(shù)組的平方
LeetCode844.比較含退格的字符串
LeetCode283.移動零
LeetCode27.移除元素
LeetCode26.刪除有序數(shù)組中的重復項
LeetCode209.長度最小的子數(shù)組

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容