前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >301. 删除无效的括号

301. 删除无效的括号

作者头像
ppxai
发布2023-11-18 08:36:20
870
发布2023-11-18 08:36:20
举报
文章被收录于专栏:皮皮星球皮皮星球

301. 删除无效的括号

Given a string s that contains parentheses and letters, remove the minimum number of invalid parentheses to make the input string valid.

Return all the possible results. You may return the answer in any order.

Example 1:

代码语言:javascript
复制
Input: s = "()())()"
Output: ["(())()","()()()"]

Example 2:

代码语言:javascript
复制
Input: s = "(a)())()"
Output: ["(a())()","(a)()()"]

Example 3:

代码语言:javascript
复制
Input: s = ")("
Output: [""]

Constraints:

  • 1 <= s.length <= 25
  • s consists of lowercase English letters and parentheses '(' and ')'.
  • There will be at most 20 parentheses in s.
思路
  1. 首先明确两点:判断字符串是否是合法的左右括号,从左往右遍历字符串的时候,任意时刻,一定是右括号小于等于左括号,否则就是不合法的; 而整个字符串的括号都合法,左右括号数一定一样。
代码语言:javascript
复制
// 判断字符串是否是合法的左右括号
func getParenthesesNums(s string) (left, right int, isValid bool) {
    isValid = true
    for i := range s {
        if s[i] == '(' {
            left++
        } else if s[i] == ')' {
            if left != 0 {
                left--
            } else {
                right++
            }

            // 任意时刻,一定是右括号小于等于左括号,否则就是不合法的,
            // 但是需要计算非法左右括号数,所以循环继续,比如()())(
            if right > left {
                isValid = false
            }
        }
    }
    return
}
  1. 第二就考虑怎么删除多余的括号,来保证字符串是合法的。这里就可以针对每一个括号,移除以后,递归处理剩下的字符串是否是合法的。递归终止条件就是没有要移除的括号了。需要特别处理的就是有相邻重复括号的时候,如果我们都去删除的话,会产生重复解,可以考虑都只移除第一个来进行剪枝,避免重复计算。
代码语言:javascript
复制
func dfs(s string, start, left int, right int, res *[]string) {
    if 0 == left && 0 == right {
        // 判断是否字符串是否合法
        if _, _, isValid := getParenthesesNums(s); isValid {
            *res = append(*res, s)
        }
        return
    }
        fmt.Println(left, right)
    // 如果需要删除的左括号和右括号不为零,就遍历字符串,找到可以删除的位置
    for i := start; i < len(s); i++ {
        if i != start && s[i] == s[i-1] {
            //说明存在括号重复,只删第一个,来处理就行
            continue
        }

        if s[i] == '(' && left > 0 {
            cur := string(append([]byte(s[:i]), s[i+1:]...))
            // fmt.Println(s, cur)
            dfs(cur, i, left-1, right, res)
        }

        if s[i] == ')' && right > 0 {
            cur := string(append([]byte(s[:i]), s[i+1:]...))
            // fmt.Println(cur)
            dfs(cur, i, left, right-1, res)
        }
    }

    return
}
完整代码:
代码语言:javascript
复制
func removeInvalidParentheses(s string) []string {
    // 1. 找出不合法的左括号和右括号数
    // 从左往右遍历的时候,在任意时刻,右括号数一定要小于左括号数
    left, right, _ := getParenthesesNums(s)

    // 2. 从第0位开始扫描,逐个去尝试移除括号之后的字符串中的括号是否合法
    var res = make([]string, 0)
    dfs(s, 0, left, right, &res)
    return res
}

func dfs(s string, start, left int, right int, res *[]string) {
    if 0 == left && 0 == right {
        // 判断是否字符串是否合法
        if _, _, isValid := getParenthesesNums(s); isValid {
            *res = append(*res, s)
        }
        return
    }
        fmt.Println(left, right)
    // 如果需要删除的左括号和右括号不为零,就遍历字符串,找到可以删除的位置
    for i := start; i < len(s); i++ {
        if i != start && s[i] == s[i-1] {
            //说明存在括号重复,只删第一个,来处理就行
            continue
        }

        if s[i] == '(' && left > 0 {
            cur := string(append([]byte(s[:i]), s[i+1:]...))
            // fmt.Println(s, cur)
            dfs(cur, i, left-1, right, res)
        }

        if s[i] == ')' && right > 0 {
            cur := string(append([]byte(s[:i]), s[i+1:]...))
            // fmt.Println(cur)
            dfs(cur, i, left, right-1, res)
        }
    }

    return
}

// 判断字符串是否是合法的左右括号
func getParenthesesNums(s string) (left, right int, isValid bool) {
    isValid = true
    for i := range s {
        if s[i] == '(' {
            left++
        } else if s[i] == ')' {
            if left != 0 {
                left--
            } else {
                right++
            }

            // 任意时刻,一定是右括号小于等于左括号,否则就是不合法的,
            // 但是需要计算非法左右括号数,所以循环继续,比如()())(
            if right > left {
                isValid = false
            }
        }
    }
    return
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 301. 删除无效的括号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档