算法(26)-最长系列
最長系列
- 1.LeetCode-32 最長有效括號--子串
- 2.LeetCode-300 最長上升子序列--長度
- 3.LeetCode-32 最長回文子串--是什么
- 5.LeetCode-512 最長回文子序列--長度
- 6.LeetCode-1143 最長公共子序列--長度
- 6.LeetCode-128 最長連續序列--長度
- 7.LeetCode-14 最長公共前綴-字符串
- 8.劍指offer-48 最長不含重復字符串的子字符串-長度
列表-子序列(連續/不連續)
字符串-子序列(不連續),子串(連續)
1.一維dp,dp[i] --以item[i]結尾的,有效的,最長XXX的長度
1.LeetCode-32 最長有效括號–子串
題目:給定一個只包含 ‘(’ 和 ‘)’ 的字符串s,找出最長的包含有效括號的子串的長度。
dp[i] --以s[i]結尾的,有效的子串的長度中,最長的一個。
顯然有效的子串一定以)結尾,因此我們可以知道以(結尾的子串對應的dp 值必定為 0,我們只需要求解 )在dp 數組中對應位置的值。
同時因為子串要求連續,所以可以用相鄰的dp[i-2]來更新符合條件的dp[i](s[i]==")"ands[i?1]=="("=>dp[i]=dp[i?2]+2s[i]==")" and \ s[i-1]=="("=>dp[i] = dp[i-2]+2s[i]==")"and?s[i?1]=="("=>dp[i]=dp[i?2]+2})
# 1.s[i]==")" and s[i-1]=="(" dp[i] = dp[i-2]+2 # 2.s[i]==")" and s[i-1]==")" dp[i] = dp[i-1] + dp[i-dp[i-1]-2]+2 下標的合理性 # ((xx)) dp[i-1] 也有效的情況下 def longestValidParentheses(self, s):n=len(s)if n<2:return 0dp=[0]*nres=0for i in range(1,n):if i==1:if s[i]==")" and s[i-1]=="(":dp[1]=2else:if s[i]==")" and s[i-1]=="(":dp[i]=dp[i-2]+2 if s[i]==")" and s[i-1]==")":if i-1-dp[i-1]>=0 and s[i-1-dp[i-1]]=="(":dp[i]=dp[i-1]+2 # if i-2-dp[i-1]>=0:dp[i]+=dp[i-2-dp[i-1]]res=max(res,dp[i]) return res2.LeetCode-300 最長上升子序列–長度
題目:給定一個無序的整數數組,找到其中最長上升子序列的長度。
輸入: [10,9,2,5,3,7,101,18] 輸出: 4 解釋: 最長的上升子序列是 [2,3,7,101],它的長度是 4。dp[i] --以nums[i]結尾的,上升序列的長度中,最長的一個。
def lengthOfLIS(self, nums):""":type nums: List[int]:rtype: int"""# dp[i]表示以nums[i]為結尾的最長上升子序列的長度n = len(nums)if n < 2:return ndp = [1] * nres = 0for i in range(1,n):for j in range(i):if nums[j]< nums[i]:dp[i] = max(dp[i], dp[j]+1)res = max(res, dp[i]) # 這么寫就需要考慮初值為1的時候return res2.維度d
3.LeetCode-32 最長回文子串–是什么
獨自一個人也,也可以二維dp, 強!二維dp實際上也是以每個字符為中心向兩邊擴展的情況。
dp[i][j] 表示s[i]-s[j]子串是否是回文子串,依賴于s[i]==s[j] and dp[i+1][j-1]
狀態轉移決定了dp初始化元素(對角線)和更新的方向(由下向上,由對角線往右)
5.LeetCode-512 最長回文子序列–長度
和上題的基本思路一樣,不過dp數組表示的含義變為
dp[i][j] 表示s[i]-s[j]子串中回文序列的長度
6.LeetCode-1143 最長公共子序列–長度
(兩個字符串,二維dp 才是標配嘛)
dp[i][j] 表示s1[0]-s1[i] 于s2[0]-s2[j] 的最長公共子序序列,更新形式于512題類似,只不過初值和方向不大一樣,初值為第0行第0列均為0,方向由上到下,由左到右。
3.帶技巧解題
6.LeetCode-128 最長連續序列–長度
給定一個未排序的整數數組,找出最長連續序列的長度。要求算法的時間復雜度為 O(n)。
數組本身無序,連續序列有序,只要能找到連續序列的開頭,就能確定序列長度,迭代更新最長長度就可以了。
def longestConsecutive(self, nums):if not nums:return 0res = 1nums_set = set(nums)for val in nums_set:if val - 1 not in nums_set: # val 為連續序列的開頭count = 1num = valwhile(num + 1 in nums_set):count += 1num = num + 1res = max(res, count)return res7.LeetCode-14 最長公共前綴-字符串
暴力法:縱向掃描
先驗:最長公共前綴不回比最短的字符串長,所以先求出最短的長度。
8.劍指offer-48 最長不含重復字符串的子字符串-長度
請從字符串中找出一個最長的不包含重復字符的子字符串,計算該最長子字符串的長度。
輸入: "abcabcbb" 輸出: 3 解釋: 因為無重復字符的最長子串是 "abc",所以其長度為 3。移動窗口,保證窗口內的字符無重復,如果有重復就縮小窗口。
def lengthOfLongestSubstring(self, s):""":type s: str:rtype: int"""win = {}left, right = 0, 0n = len(s)res = 0while (right < n):c1 = s[right]if win.get(c1):win[c1] += 1else:win[c1] = 1right += 1while(win[c1]>1):c2 = s[left]win[c2] -=1left += 1res = max(res, right - left)return res總結
以上是生活随笔為你收集整理的算法(26)-最长系列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Python Cookbook 3rd
- 下一篇: 算法(18)-leetcode-剑指of