Day 2 數(shù)組拓展:904. 水果成籃, 76. 最小覆蓋子串, 54. 螺旋矩陣, 48. 旋轉圖像; 數(shù)組總結

904. 水果成籃

  • 思路
    • example
    • 兩個籃子恨统,返回你可以收集的水果的 最大 數(shù)目
    • 等價于“最長的含兩個不同數(shù)字的連續(xù)子序列長度”
    • Two Pointer, Sliding Window, -->-->
      • left, right = 0, 0
      • use hash, i.e., dict to record the fruits
      • dict[num] = freq
      • len(dict) is always <= 2
      • [left, right] is feasible if len(dict) <= 2,左閉右閉,可行窗口
  • 注意最大最小的處理邏輯不同衅码。

本題

遍歷 right:
    處理right
    循環(huán)收縮left找到可行窗口
    處理可行窗口
  • 復雜度. 時間:O(n), 空間: O(1)
class Solution:
    def totalFruit(self, fruits: List[int]) -> int:
        n = len(fruits)
        left, right = 0, 0
        basket = collections.defaultdict(int)
        res = 0
        while right < n:
            # "add"/test current fruit into the basket
            basket[fruits[right]] += 1
            # then check the feasibility
            while len(basket) > 2: # more than 2 types of fruits, [left, right] is not feasible
                # move left
                basket[fruits[left]] -= 1
                if basket[fruits[left]] == 0:
                    del basket[fruits[left]] # need to del this otherwise we could not use len(basket)
                left += 1
            # [left, right] is feasible, update res
            res = max(res, right - left + 1)
            # move right
            right += 1
        return res
  • try this
import collections
dict1 = collections.defaultdict(int)
print(dict1)
print(dict1[2])
print(len(dict1))
print(dict1[3])
print(len(dict1))
print(dict1)

76. 最小覆蓋子串

  • 思路
    • example
    • 等價于“最短的連續(xù)子串(包含t)"
    • sliding window, -->-->
      • left, right = 0, 0
      • two hashes, cnt_s, cnt_t, "cnt[ch] = freq"
      • feasible window [left, right]
        • valid == len(t) (valid always <= len(t))
        • it's possible that cnt_s[ch] > cnt_t[ch] for some ch in s[left: right+1]
      • once find a feasible window, keep moving left to update the result (needs smallest substring)
      • Key: for a feasible window, cnt_s[s[right]] is exactly equal to cnt_t[s[right]]
hash: cnt_s (變化)漂羊,cnt_t (不變)
valid記錄當前窗口含有t元素的個數(shù)蒙挑。(valid 最大值n)
遍歷right:
    處理right (更新cnt_s, valid)
    如果窗口可行(size=n), 循環(huán)收縮left找到滿足要求的最小窗口 (更新cnt_s, valid, 答案)
  • 復雜度. 時間:O(n), 空間: O(1)
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        m, n = len(s), len(t)
        if m < n:
            return ''
        # fix cnt_t
        cnt_t = collections.defaultdict(int) 
        for ch in t:
            cnt_t[ch] += 1
        #
        cnt_s = collections.defaultdict(int) 
        left, right = 0, 0
        valid = 0
        start, end = 0, -1
        min_len = float('inf') # smallest length of feasible window
        while right < m:
            ch = s[right]
            cnt_s[ch] += 1
            if cnt_s[ch] <= cnt_t[ch]: # add one valid char
                valid += 1
            while valid == n: # [left, right] is a feasible, keep moving left to find the smallest window
                cur_len = right - left + 1
                if cur_len < min_len:
                    min_len = cur_len
                    start, end = left, right # record
                cnt_s[s[left]] -= 1
                if cnt_s[s[left]] < cnt_t[s[left]]: # cnt_t[s[left]] is at least 0 (defaultdict)
                    valid -= 1
                left += 1
            # move right
            right += 1
        return s[start:end+1]
  • version 2: 每一步都把left指針移動到“最佳“位置幼东。
    • Key: for a feasible window, cnt_s[s[left]] is exactly equal to cnt_t[s[left]]
hash: cnt_s (變化)确镊,cnt_t (不變)
valid記錄當前窗口含有t元素的個數(shù)士骤。(valid 最大值n)
遍歷right:
    處理right (更新cnt_s, valid)
    循環(huán)收縮left直到左邊界處在最佳位置 (cnt_s[s[left]] == cnt_t[s[left]]),結束后得到“預可行”窗口(valid < n)
    如果窗口可行蕾域,更新最小值
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        m, n = len(s), len(t)
        if m < n:
            return ''
        # fix cnt_t
        cnt_t = collections.defaultdict(int) 
        for ch in t:
            cnt_t[ch] += 1
        #
        cnt_s = collections.defaultdict(int) 
        left, right = 0, 0
        valid = 0
        start, end = 0, -1
        min_len = float('inf') # smallest length of feasible window
        while right < m:
            ch = s[right]
            cnt_s[ch] += 1
            if cnt_s[ch] <= cnt_t[ch]: # add one valid char
                valid += 1
            # keep moving left to remove the unnecessary char, until cnt_s[s[left]] == cnt_t[s[left]] 
            while left <= right and cnt_s[s[left]] > cnt_t[s[left]]:
                cnt_s[s[left]] -= 1
                left += 1
            # check feasibility
            if valid == n: # now [left, right] will be the shortest feasible substring 
                cur_len = right - left + 1
                if cur_len < min_len:
                    min_len = cur_len 
                    start, end = left, right 
            # move right
            right += 1
        return s[start:end+1]

54. 螺旋矩陣

  • 思路
    • example
    • size of matrix: m \times n
    • slightly change the update style inside the loop
      • 貪心策略:右拷肌,下,左旨巷,上巨缘。每個方向都盡可能搜索,這樣可以方便處理單行單列的情況采呐。
    • deal with the boundary case (eg., one row, one column)
    • should work for m==n case
  • 復雜度. 時間:O(n^2), 空間: O(1)
class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        m, n = len(matrix), len(matrix[0])
        top, bottom = 0, m-1
        left, right = 0, n-1
        res = []
        while top <= bottom and left <= right:
            #-->
            for j in range(left, right+1):
                res.append(matrix[top][j])
            # downward (right column)
            for i in range(top+1, bottom+1):
                res.append(matrix[i][right])
            #<--
            if top < bottom and left < right: # extra row or column updates
                for j in range(right-1, left-1, -1):
                    res.append(matrix[bottom][j])
                for i in range(bottom-1, top, -1):
                    res.append(matrix[i][left])
            # update indices
            top += 1
            bottom -= 1
            left += 1
            right -= 1
        return res

48. 旋轉圖像

  • 思路
    • example
    • size of matrix: n \times n

先按主對角線翻轉
再每一行進行翻轉



class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        def reverse(nums):
            n = len(nums)
            left, right = 0, n-1
            while left < right:
                nums[left], nums[right] = nums[right], nums[left]
                left += 1
                right -= 1
        # step 1
        n = len(matrix)
        for i in range(n):
            for j in range(i+1, n):
                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
        # step 2
        for i in range(n):
            reverse(matrix[i])

數(shù)組總結

  1. 二分搜索
  • 左閉右閉
  • 左閉右開
  1. 雙指針
  • 快慢若锁,前后, 斧吐。又固。。
  • 滑動窗口
    • 同向移動 -->-->
    • left, right 初始化
    • 外層循環(huán):right
    • 內層:left
    • 判斷當前窗口可行性煤率,移動left
      • 計數(shù)
      • hash技術
    • 滑動窗口:本質是滿足了單調性,即左右指針只會往一個方向走且不會回頭仰冠。收縮的本質即去掉不再需要的元素。也就是做題我們可以先固定移動右指針蝶糯,判斷條件是否可以收縮左指針算范圍洋只。大家可以好好理解一下。From 芒果冰
    • <--*-->
    • -->*<--
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末昼捍,一起剝皮案震驚了整個濱河市识虚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌妒茬,老刑警劉巖担锤,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異乍钻,居然都是意外死亡妻献,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門团赁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谨履,你說我怎么就攤上這事欢摄。” “怎么了笋粟?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵怀挠,是天一觀的道長析蝴。 經(jīng)常有香客問我,道長绿淋,這世上最難降的妖魔是什么闷畸? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮吞滞,結果婚禮上佑菩,老公的妹妹穿的比我還像新娘。我一直安慰自己裁赠,他們只是感情好殿漠,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著佩捞,像睡著了一般绞幌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上一忱,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天莲蜘,我揣著相機與錄音,去河邊找鬼帘营。 笑死票渠,一個胖子當著我的面吹牛,可吹牛的內容都是我干的仪吧。 我是一名探鬼主播庄新,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼薯鼠!你這毒婦竟也來了择诈?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤出皇,失蹤者是張志新(化名)和其女友劉穎羞芍,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體郊艘,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡荷科,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了纱注。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畏浆。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖狞贱,靈堂內的尸體忽然破棺而出刻获,到底是詐尸還是另有隱情,我是刑警寧澤瞎嬉,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布蝎毡,位于F島的核電站厚柳,受9級特大地震影響,放射性物質發(fā)生泄漏沐兵。R本人自食惡果不足惜别垮,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扎谎。 院中可真熱鬧碳想,春花似錦、人聲如沸簿透。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽老充。三九已至葡盗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啡浊,已是汗流浹背觅够。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留巷嚣,地道東北人喘先。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像廷粒,于是被迫代替她去往敵國和親窘拯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內容