题目描述: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。