自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解滑動(dòng)窗口最值問題

開發(fā) 前端
滑動(dòng)問題包含一個(gè)滑動(dòng)窗口,它是一個(gè)運(yùn)行在一個(gè)大數(shù)組上的子列表,該數(shù)組是一個(gè)底層元素集合。一般用來求最值問題。

[[373481]]

 滑動(dòng)問題包含一個(gè)滑動(dòng)窗口,它是一個(gè)運(yùn)行在一個(gè)大數(shù)組上的子列表,該數(shù)組是一個(gè)底層元素集合。一般用來求最值問題。

LeetCode 第 239 題:滑動(dòng)窗口最大值

題目來源于 LeetCode 上第 239 號問題:滑動(dòng)窗口最大值。題目難度為 Hard 。

給定一個(gè)數(shù)組 nums,有一個(gè)大小為 k 的滑動(dòng)窗口從數(shù)組的最左側(cè)移動(dòng)到數(shù)組的最右側(cè)。你只可以看到在滑動(dòng)窗口內(nèi)的 k 個(gè)數(shù)字?;瑒?dòng)窗口每次只向右移動(dòng)一位。

  1. 輸入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3 
  2. 輸出: [3,3,5,5,6,7]  
  3. 解釋:  
  4.  
  5.   滑動(dòng)窗口的位置                最大值 
  6. ---------------                ----- 
  7. [1  3  -1] -3  5  3  6  7       3 
  8.  1 [3  -1  -3] 5  3  6  7       3 
  9.  1  3 [-1  -3  5] 3  6  7       5 
  10.  1  3  -1 [-3  5  3] 6  7       5 
  11.  1  3  -1  -3 [5  3  6] 7       6 
  12.  1  3  -1  -3  5 [3  6  7]      7 

看到這個(gè)題之后,第一直覺就是暴力解法,用兩層循環(huán)依次查詢滑動(dòng)窗口的最大值,實(shí)現(xiàn)代碼如下。

  1. nums = [1, 3, -1, -3, 5, 3, 6, 7] 
  2. k = 3 
  3. res = [] 
  4. for i in range(k, len(nums) + 1): 
  5.     res.append(max(nums[i - k:i])) 
  6. print(res)  #[3, 3, 5, 5, 6, 7] 

但max執(zhí)行效率卻很低,在Leetcode上不能通過,因此我們需要繼續(xù)找尋新的解決方案。

雙端隊(duì)列

Deque 的含義是 “double ended queue”,即雙端隊(duì)列,它具有隊(duì)列和棧的性質(zhì)的數(shù)據(jù)結(jié)構(gòu)。顧名思義,它是一種前端與后端都支持插入和刪除操作的隊(duì)列。

在Python中,我直接使用列表代替雙端隊(duì)列,pop(0)表示前端刪除操作,pop()表示后端刪除操作。

雙端隊(duì)列window記錄滑動(dòng)窗口中元素的索引,隊(duì)列左邊界記錄當(dāng)前滑動(dòng)窗口中最大元素的索引

  • 當(dāng)隊(duì)列非空,左邊界出界時(shí)(滑動(dòng)窗口向右移導(dǎo)致的),更新左邊界
  • 當(dāng)隊(duì)列非空,將隊(duì)列中索引對應(yīng)的元素值比 num 小的移除,更新隊(duì)列
  • 當(dāng)索引 i 大于 k-1,更新輸出結(jié)果
  1. class Solution: 
  2.     def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]: 
  3.         if not  nums: return [] 
  4.         window ,res = [],[] 
  5.         for i,x in enumerate(nums): 
  6.             # 如果存在窗口 而且窗口的第一個(gè)數(shù) 不在這個(gè)范圍,就出去 
  7.             if i >= k and window[0] <= i-k: 
  8.                 window.pop(0) 
  9.             # 每次進(jìn)入窗口的和最后一個(gè)比較,如果大了,最后一個(gè)直接刪除 
  10.             while window and nums[window[-1]] <= x: 
  11.                 window.pop() 
  12.             # 無論是不是刪除最后一個(gè),都要加入x到窗口中 
  13.             window.append(i) 
  14.             # 如果出了窗口,就把窗口的頭加入到res中 
  15.             if i >= k-1: 
  16.                 res.append(nums[window[0]]) 
  17.         return res 

LeetCode 第 3 題 無重復(fù)字符的最長子串

給定一個(gè)字符串,請你找出其中不含有重復(fù)字符的 最長子串 的長度。

  1. # 示例 1: 
  2. # 輸入: "abcabcbb" 
  3. # 輸出: 3 
  4. #解釋: 因?yàn)闊o重復(fù)字符的最長子串是 "abc",所以其長度為 3。 
  5. # 示例 2: 
  6. # 輸入: "bbbbb" 
  7. #輸出: 1 
  8. #解釋: 因?yàn)闊o重復(fù)字符的最長子串是 "b",所以其長度為 1。 
  9. # 示例 3 
  10. # 輸入: "pwwkew" 
  11. #輸出: 3 
  12. #解釋: 因?yàn)闊o重復(fù)字符的最長子串是 "wke",所以其長度為 3。 
  13. #請注意,你的答案必須是 子串 的長度,"pwke" 是一個(gè)子序列,不是子串。 

下面我們看看,“滑動(dòng)窗口”如何進(jìn)行字符串處理。結(jié)合題目中的例子“abcabcbb”這個(gè)字符串,我們來看看如何找它的無重復(fù)最長子串。

首先,我們定義窗口的兩端:begin和end,分別表示要找的子串的開頭和結(jié)尾。


開始的時(shí)候,begin和end都指向0的位置即‘a’,然后end不斷后移(窗口變寬),當(dāng)遇到第二個(gè)‘a’時(shí)(遇見重復(fù)字符)就得到一個(gè)子串,其長度就是end和begin位置的差。

如何判斷是否遇到了重復(fù)字符‘a’呢?需要一個(gè)字典作為輔助數(shù)據(jù)結(jié)構(gòu),把end從頭開始遇到的每個(gè)字符及其索引位置都放到字典里面,end每次移動(dòng)到新字符就查一下字典即可

  1. class Solution: 
  2.     def lengthOfLongestSubstring(self, s: str) -> int
  3.         # 定義兩個(gè)變量res和start,res用于存儲(chǔ)最長子字符串的長度,start存儲(chǔ)無重復(fù)子串左邊的起始位置。 
  4.         ''
  5.         然后創(chuàng)建一個(gè)哈希表,遍歷整個(gè)字符串,如果字符串沒有在哈希表中出現(xiàn),說明沒有遇到過該字符,則此時(shí)計(jì)算最長無重復(fù)子串,當(dāng)哈希表中的值小于left,說明left位置更新了,需要重新計(jì)算最長無重復(fù)子串。每次在哈希表中將當(dāng)前字符串對應(yīng)的賦值加1。 
  6.         :param s: 
  7.         :return
  8.         ''
  9.         d, res, start = {}, 0, 0 
  10.         for i, ch in enumerate(s): 
  11.             if ch in d: 
  12.                 start = max(start, d[ch] + 1) 
  13.             res = max(res, i - start + 1) 
  14.             d[ch] = i 
  15.         return res 

人生最重要的不是所站的位置,而是內(nèi)心所朝的方向。只要我在每篇博文中寫得自己體會(huì),修煉身心;在每天的不斷重復(fù)學(xué)習(xí)中,耐住寂寞,練就真功,不畏艱難,奮勇前行,不忘初心,砥礪前行,人生定會(huì)有所收獲,不留遺憾 (作者:Runsen )

本文已收錄 GitHub  https://github.com/MaoliRUNsen/runsenlearnpy100

 

責(zé)任編輯:姜華 來源: Python之王
相關(guān)推薦

2021-08-25 09:49:48

鴻蒙HarmonyOS應(yīng)用

2023-08-11 07:44:40

TCP滑動(dòng)窗口數(shù)據(jù)

2021-11-12 09:30:46

滑動(dòng)窗口算法

2012-08-29 09:32:10

大數(shù)據(jù)存儲(chǔ)Hadoop

2023-08-26 20:56:02

滑動(dòng)窗口協(xié)議

2023-05-15 07:32:01

算法訓(xùn)練滑動(dòng)窗口

2021-10-14 08:19:50

雙指針滑動(dòng)窗口算法

2009-11-26 14:23:11

Silverlight

2015-01-15 09:21:24

TCP窗口

2011-08-17 14:30:34

iOS開發(fā)窗口

2013-11-18 10:04:31

TCP 滑動(dòng)窗口

2011-08-01 15:58:23

惠普激光打印機(jī)

2024-08-02 15:47:28

數(shù)據(jù)庫分庫分表

2009-07-06 10:00:31

JSP頁面?zhèn)髦?/a>

2023-09-13 08:37:56

程序員面試catch

2015-05-25 11:10:49

2023-07-03 08:20:35

MySQL窗口函數(shù)

2020-08-13 08:43:24

TCP固定窗口滑動(dòng)窗口

2021-02-02 14:41:11

NumPy開發(fā)程序

2023-09-26 08:39:28

限流方式滑動(dòng)窗口計(jì)數(shù)器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號