題目描述:python
給定一個只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串,判斷字符串是否有效。算法
有效字符串需知足:數組
注意空字符串可被認爲是有效字符串。app
示例:spa
示例 1:
輸入: "()" 輸出: true 示例 2: 輸入: "()[]{}" 輸出: true 示例 3: 輸入: "(]" 輸出: false 示例 4: 輸入: "([)]" 輸出: false 示例 5: 輸入: "{[]}" 輸出: true
【思路】用棧保存括號的左半部分,遇到左半部分就入棧;遇到右半部分就查看棧頂元素是否與該括號爲一對,若是是,就將棧頂元素出棧,不然,返回錯誤,表示該串括號無效。code
代碼以下:blog
def isValid(s): stack_ = [] if s == '': return True if len(s) == 1: return False list_s = list(s) for i in range(len(list_s)): if list_s[i] == '(' or list_s[i] == '[' or list_s[i] == '{': stack_.append(s[i]) else: print('stack_',stack_) if len(stack_) > 0: if stack_[-1] == None: return False if list_s[i] == ')' and stack_[-1] != '(': return False elif list_s[i] == ']' and stack_[-1] != '[': return False elif list_s[i] == '}' and stack_[-1] != '{': return False if list_s[i] and stack_ == []: return False stack_ = stack_[:-1] return stack_ == [] res = isValid('[]]') print(res)
題目描述:給定一個只包含 '(' 和 ')' 的字符串,找出最長的包含有效括號的子串的長度。遞歸
示例:leetcode
示例 1:
輸入: "(()" 輸出: 2 解釋: 最長有效括號子串爲 "()" 示例 2: 輸入: ")()())" 輸出: 4 解釋: 最長有效括號子串爲 "()()"
思路:基於判斷括號有效子集的方法擴展,主要思想是掃描字符串,遇到「(」的時候,將對應的index存儲在stack中,遇到「)」的時候,意味着可能遇到了一個有效子字符串,因此須要維護一個maximam變量。 計算maximum的方法是,存一個start變量,是咱們認爲的有效的子集開始的位置,而後遍歷字符串,利用不一樣的位置減去start獲得的值,來維護maximum。字符串
時間複雜度:O(n)
空間複雜度:O(n)
代碼以下:
def longestValidParentheses(s): stack = [] start = 0 maximum = 0 for i in range(len(s)): if s[i] == '(': stack.append(i) else: if stack == []: start = i + 1 else: stack.pop() if stack != []:#說明是)前面緊跟着( maximum = max(maximum,i-stack[-1]) else:#說明)前面有不止一個(,就要計算start到當前i的距離 maximum = max(maximum,i-start+1) return maximum
題目描述:
給定一個平衡括號字符串S,按下述規則計算該字符串的分數:
()得1分。
AB得A + B分,其中A和B是平衡括號字符串。
(A)得2 * A分,其中A是平衡括號字符串。
示例:
示例1:
輸入: "()" 輸出: 1 示例2: 輸入: "(())" 輸出: 2 示例3: 輸入: "()()" 輸出: 2 示例4: 輸入: "(()(()))" 輸出: 6 提示:S是平衡括號字符串,且只含有(和)。2 <= S.length <= 50
思路1:遞歸
對給定的字符串,找出與最左邊的括號相匹配的右括號的下標index,若是這兩個括號正好佔據了字符串一左一右的兩側邊界,則最後的分數爲這兩個括號中間部分的子字符串的分數 * 2。不然最後的分數等於下標index將S分紅的左右兩個平衡括號字符串分數之和。
思路2:棧
括號匹配的題目通常要用到棧,這個題也是。咱們用棧保存兩樣東西:一是左括號(,二是得分。這樣咱們在遇到)返回的時候,能夠直接判斷棧裏面是左括號仍是得分。
若是是左括號(,那麼得分是1,放入棧中。
若是是得分,那麼咱們須要一直向前求和直到找到左括號爲止,而後把這個得分×2,放入棧中。
因爲題目給的是符合要求的括號匹配對,那麼棧裏面最後應該只剩下一個元素了,就是最終得分。
思路1代碼:
from collections import OrderedDict class Solution (object): # 找第一個左括號的右括號對應的右括號的位置 def FindFirstRightkh(self,S): stack = [] dict_S = OrderedDict() for idx,s in enumerate(list(S)): if s == '(': stack.append(idx) elif s == ')' and len(stack) >= 1: dict_S[stack[-1]] = idx if stack[-1] == 0: return idx stack.pop() # print(dict_S) #{1: 2, 4: 5, 3: 6, 0: 7} def scoreOfParentheses(self, S): score = 0 if S == '()': return 1 elif S =='(())': return 2 elif S == '()()': return 2 idx_Rightkh = self.FindFirstRightkh(S) if idx_Rightkh == len(S) - 1: score = 2 * self.scoreOfParentheses(S[1:idx_Rightkh]) else: score = self.scoreOfParentheses(S[:idx_Rightkh+1]) + self.scoreOfParentheses(S[idx_Rightkh+1:]) return score
思路2代碼:
class Solution1 (object): def scoreOfParentheses1(self, S): """ :type S: str :rtype: int """ scoreStack = [] for c in S: if c == '(': #若是是'(',就將-1入棧 scoreStack.append(-1) else:#右括號 score = 0 while scoreStack[-1] != -1:#若是是得分,就一直加,直到遇到-1,獲得內部的括號之和 score += scoreStack.pop() scoreStack.pop()#彈出不是-1的 if score == 0: scoreStack.append(1) else: #得分不爲0,說明棧頂不爲-1,得2倍分 scoreStack.append(2 * score) totalScore = 0 while scoreStack != []: totalScore += scoreStack.pop() return totalScore s = Solution() res = s.scoreOfParentheses(S='((())(()))') print(res)
題目描述:給定一個由'('和')'括號組成的字符串S,咱們須要添加最少的括號( '('或是')',能夠在任何位置),以使獲得的括號字符串有效
說明:從形式上講,只有知足下面幾點之一,括號字符串纔是有效的:
它是一個空字符串,或者它能夠被寫成AB(A與B鏈接), 其中A和B都是有效字符串,或者它能夠被寫做 (A),其中A是有效字符串。
給定一個括號字符串,返回爲使結果字符串有效而必須添加的最少括號數。
示例1:
輸入:"())" 輸出:1 示例2: 輸入:"(((" 輸出:3 示例3: 輸入:"()" 輸出:0 示例4: 輸入:"()))((" 輸出:4 提示: S.length <= 1000 S只包含'('和')'字符。
思路:
代碼以下:
class Solution: def minAddToMakeValid(self, S): """ :type S: str :rtype: int """ if S == '': return 0 stack = [] right_kh_count = 0 left_kh_count = 0 for s in S: if s == '(': stack.append(s) elif s == ')' and stack != []: stack.pop() else: left_kh_count += 1 if stack != []: right_kh_count = len(stack) return left_kh_count + right_kh_count def minAddToMakeValid_leetcode(self, S): if S == '': return 0 stack = [] for s in S: if s == ')' and len(stack) >0 and stack[-1] == '(': stack.pop() else: stack.append (s) return len(stack) s = Solution() num = s.minAddToMakeValid_leetcode(S='())') print(num)
題目描述:給定兩個沒有重複元素的數組 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每一個元素在 nums2 中的下一個比其大的值。
說明:nums1 中數字 x 的下一個更大元素是指 x 在 nums2 中對應位置的右邊的第一個比 x 大的元素。若是不存在,對應位置輸出-1。
示例:
示例 1: 輸入: nums1 = [4,1,2], nums2 = [1,3,4,2]. 輸出: [-1,3,-1] 解釋: 對於num1中的數字4,你沒法在第二個數組中找到下一個更大的數字,所以輸出 -1。 對於num1中的數字1,第二個數組中數字1右邊的下一個較大數字是 3。 對於num1中的數字2,第二個數組中沒有下一個更大的數字,所以輸出 -1。
示例 2: 輸入: nums1 = [2,4], nums2 = [1,2,3,4]. 輸出: [3,-1] 解釋: 對於num1中的數字2,第二個數組中的下一個較大數字是3。 對於num1中的數字4,第二個數組中沒有下一個更大的數字,所以輸出 -1。
注意: nums1和nums2中全部元素是惟一的。 nums1和nums2 的數組大小都不超過1000。