zoukankan      html  css  js  c++  java
  • 括号字符串

     

    目录

    题目、有效的括号字符串(1):【两个栈】

    给定一个只包含三种字符的字符串:(  和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:

    1. 任何左括号 ( 必须有相应的右括号 )
    2. 任何右括号 ) 必须有相应的左括号 ( 。
    3. 左括号 ( 必须在对应的右括号之前 )
    4. * 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
    5. 一个空字符串也被视为有效字符串。

    示例 1:

    输入: "()"
    输出: True
    

    示例 2:

    输入: "(*)"
    输出: True
    

    示例 3:

    输入: "(*))"
    输出: True
    

    思路1:时间O(n2),空间O(n)

    采用1个栈存(),同时存索引

    采用第2个栈存*,同时存索引

    两个for循环比较两个栈。

    代码:

        def checkValidString(self, s):
            """
            :type s: str
            :rtype: bool
            """
            #采用两个栈来解决
            if not s:
                return True
            n = []
            stack = []
            for i,ss in enumerate(s):
                if ss == '(':
                    stack.append((i,ss))
                elif ss == ')':
                    if stack and stack[-1][1] == '(':
                        stack.pop()
                    else:
                        stack.append((i,ss))
                elif ss == '*':
                    n.append(i)
            print(stack)  
            i , j = 0 , 0
            ca = True
            while i < len(stack):
                while j < len(n) and len(stack) > 0:
                    if stack[i][1] == ')' and stack[i][0] >= n[j] or (stack[i][1] == '(' and stack[i][0] <= n[j]):
                        stack.pop(i)
                        n.pop(j)
                        ca = False 
                        j -= 1
                    j += 1
                if ca:
                    i += 1
                if j == len(n):
                    break        
            if len(stack) != 0:
                return False
            return True

    思路2:时间O(n),空间O(1)

    left变量: * 作为( 时,左括号(的数量

    right变量:*作为  )时,左括号(的数量

    如果left<0,返回False

    如果循环结束,right > 0,就返回False

        def checkValidString(s):       
             if not s:
                return True
            left , right = 0,0
            for ss in s:
                left += 1 if ss != ')' else -1
                right += 1 if ss == '(' else -1
                if left < 0:
                    return False
                right = max(right ,0 )
            return right == 0    

    题目、括号的有效性(2)

    思路:采用两个变量记录‘(’,‘)’数量

    1. 遍历,判断每个字符是否为'('')',否则不合法。
    2. 遍历同时,采用left和right记录'(',‘)’的数量,若到目前为止,‘)’比‘(’多,则不合法
    3. 遍历后,如果‘(’和‘)’数量不等,则不合法

    代码:

    def isValid(s):
        if not s or s == '':
            return False
        status = 0 #记录')'减去‘(’的数量
        for ss in s:
            if ss != '(' and ss != ')':
                return False
            if ss == '(':
                status += 1
            elif ss == ')':
                status -= 1
            if status < 0:
                return False
        return status == 0
    s = '((()()))'
    isValid(s)

    原问题思路:采用一个变量记录‘)’减去‘(’的差,若当前)-(>0则返回FALSE

    题目、判断括号字符串是否有效(3)

    给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。

    有效字符串需满足:

    1. 左括号必须用相同类型的右括号闭合。
    2. 左括号必须以正确的顺序闭合。

    注意空字符串可被认为是有效字符串。

    示例 1:

    输入: "()"
    输出: true
    

    示例 2:

    输入: "()[]{}"
    输出: true
    

    思路:采用栈,遇到左括号入栈,右括号出栈。出栈与当前符号不匹配,则不有效。

    代码:

        def isValid(self, s):
            """
            :type s: str
            :rtype: bool
            """
            if not s:
                return True
            stack = []
            for ss in s:
                if ss == '(' or ss == '{' or ss == '[':
                    stack.append(ss)
                elif ss == ']':
                    if stack and stack[-1] == '[':
                        stack.pop()
                    else:
                        return False
                elif ss == ')':
                    if stack and stack[-1] == '(':
                        stack.pop()
                    else:
                        return False
                elif ss == '}':
                    if stack and stack[-1] == '{':
                        stack.pop()
                    else:
                        return False   
            return len(stack) == 0 

    题目、最长有效括号子串

    给定一个括号字符串,求最长的有效括号子串。

     

    思路:动态规划,时间O(N),空间O(N)

    dp[i]表示从0到第i个字符串的最长有效括号子串。

    需同时考虑两种情况:

    1. 包含关系(()),dp[i] = dp[i-1] + 2【若 s [ i ] == ')' ,且 s [ i - dp [i-1] -1 ] == '('】
    2. 并列关系()(),dp[i] = dp[i] + dp [  i - dp [i-1] -2 ] 

        if not s or len(s) <= 1:
            return 0
        dp = [0] * len(s)
        res = 0
        for i in range(1,len(s)):
            if s[i] == ')':
                pre = i - dp[i-1] -1
                if pre >= 0 and s[pre] == '(':
                    #若(())这种包含关系,需加dp[i-1]+2.
                    dp[i] = dp[i-1] + 2
                    #若()()这种并列关系,需加上dp[pre-1]
                    if pre > 0:
                        dp[i] += dp[pre-1]
            res = max(res,dp[i])  
        return res

    题目:856括号的分数【栈】

    给定一个平衡括号字符串 S,按下述规则计算该字符串的分数:

    • () 得 1 分。
    • AB 得 A + B 分,其中 A 和 B 是平衡括号字符串。
    • (A) 得 2 * A 分,其中 A 是平衡括号字符串。

    示例 1:

    输入: "()"
    输出: 1
    

    示例 2:

    输入: "(())"
    输出: 2
    

    示例 3:

    输入: "()()"
    输出: 2
    

    示例 4:

    输入: "(()(()))"
    输出: 6
    

    提示:

    1. S 是平衡括号字符串,且只含有 ( 和 ) 。
    2. 2 <= S.length <= 50

     思路:

    初始 index = 0 ,初始结果列表 stack= [0]*30 【30是一个随意值,防止超出界限,stack用来存结果的。】

    ①遇到’(‘,index往前一步,遇到’)‘,index往后退一步

    ②遇到’(‘,stack[index] += max(stack[index+1],1),遇到’)‘,stack[index]  = 0

    代码:

        def scoreOfParentheses(self, S):
            res, i = [0] * 30, 0
            for c in S:
                i += 1 if c == '(' else -1
                res[i] = res[i] + max(res[i + 1] * 2, 1) if c == ')' else 0
            return res[0]

    题目:22括号生成【递归】卡诺兰数

    给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

    例如,给出 n =3,生成结果为:

    [
      "((()))",
      "(()())",
      "(())()",
      "()(())",
      "()()()"
    ]
    

    思路:

    递归条件1:left>0,则递归helper(string+'(',res,left - 1 ,right)

    递归条件2:left<right,则递归helper(string+')',res,left,right-1)

    代码:

    class Solution(object):
        def generateParenthesis(self, n):
            """
            :type n: int
            :rtype: List[str]
            """
            if n == 0:
                return []
            res = []
            def helper(subStr,res,left,right):
                if left == 0 and right == 0:
                    res.append(subStr)
                    return 
                if left > 0:
                    helper(subStr+'(',res,left-1,right)
                if left<right:
                    helper(subStr+')',res,left,right-1)
            helper("",res,n,n)
            return res
        

     

    题目:字符串解码

    给定一个经过编码的字符串,返回它解码后的字符串。

    编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

    你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

    此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

    示例:

    s = "3[a]2[bc]", 返回 "aaabcbc".
    s = "3[a2[c]]", 返回 "accaccacc".
    s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".

    思路:

    采用一个栈存储字母和数字num,【【字母1,数字1】,【字母2,数字2】……】

    遇到字母就加入栈的最后一个元素的字母中,

    遇到数字,num 存储该数字

    遇到 '[' ,栈就新增一个元素,元素包含前面数字num

    遇到 ']' , 栈就弹出最后一个元素,字母*元素,再加入前一个元素的字母中

    代码:

    class Solution(object):
        def decodeString(self, s):
            """
            :type s: str
            :rtype: str
            """
            if not s:
                return s
            res = [["",1]]
            num = ''
            
            for ss in s:
                if ss.isdigit():
                    num += ss
                elif ss == '[':
                    res.append(["",int(num)])
                    num = ''
                elif ss.isalpha():
                    res[-1][0] += ss
                elif ss == ']':
                    k,v = res.pop()
                    res[-1][0] += k*v
            return res[0][0]

     题目:交错字符串

    结果为19。

    分析:

     
  • 相关阅读:
    如何掌握所有的程序语言
    Excel技巧:如何绘制一份优秀的甘特图(项目管理)
    Excel技巧:如何绘制一份优秀的甘特图(项目管理)
    程序员的鄙视链
    程序员的鄙视链
    程序员的鄙视链
    程序员之间的鄙视链
    炮(棋盘DP)
    最长公共子上升序列
    black hack
  • 原文地址:https://www.cnblogs.com/Lee-yl/p/9840376.html
Copyright © 2011-2022 走看看