golang力扣leetcode 301.删除无效的括号

简介: golang力扣leetcode 301.删除无效的括号

301.删除无效的括号

301.删除无效的括号

题解

题目:给定包含左右括号和字母的字符串,要求删除某些括号后,该字符串括号匹配(字母不删),如果只删1个就能合法,返回所有合法字符串,如果删2个才能合法…总之删除括号的数量越少越好

思路:

dfs+回溯

1.预处理出需要删除的左右括号的个数(rmL,rmR)
2.dfs遍历字符串,如果是左括号,则
        temp := str[:i] + str[i+1:]
        dfs(temp, i, rml-1, rmR)
         右括号同理
  出口:rmL和rmR为0,并且字符串匹配

bfs

1.将字符串s存入队列
2.遍历队列,如果队列中的字符串合法则加入答案,遍历完后退出
3.如果没有合法的,则
  遍历队列,遍历字符串
        遇到括号就去除,加入队列 temp := str[:i] + str[i+1:]

代码

func removeInvalidParentheses(s string) (result []string) {
  mp := make(map[string]bool)
  rmL, rmR := 0, 0
  for _, v := range s {
    if v == '(' {
      rmL++
    } else if v == ')' {
      if rmL == 0 {
        rmR++
      } else {
        rmL--
      }
    }
  }
  var dfs func(str string, idx int, rmL, rmR int)
  dfs = func(str string, idx int, rml, rmR int) {
    if rml == 0 && rmR == 0 && isValid(str) {
      mp[str] = true
      return
    }
    if rml+rmR > len(str)-idx {
      return
    }
    for i := idx; i < len(str); i++ {
      v := str[i]
      if v == '(' && rml > 0 {
        temp := str[:i] + str[i+1:]
        dfs(temp, i, rml-1, rmR)
      }
      if v == ')' && rmR > 0 {
        temp := str[:i] + str[i+1:]
        dfs(temp, i, rml, rmR-1)
      }
    }
  }
  dfs(s, 0, rmL, rmR)
  for k := range mp {
    result = append(result, k)
  }
  return
}
func isValid(str string) bool {
  count := 0
  for _, ch := range str {
    if ch == '(' {
      count++
    } else if ch == ')' {
      count--
      if count < 0 {
        return false
      }
    }
  }
  return count == 0
}
func removeInvalidParentheses(s string) (result []string) {
  cur := make(map[string]bool)
  cur[s] = true
  for {
    for str := range cur {
      if isValid(str) {
        result = append(result, str)
      }
    }
    if len(result) > 0 {
      return result
    }
    next := make(map[string]bool)
    for str := range cur {
      for i, v := range str {
        if v == '(' || v == ')' {
          temp := str[:i] + str[i+1:]
          next[temp] = true
        }
      }
    }
    cur = next
  }
}
func isValid(s string) bool {
  count := 0
  for _, v := range s {
    if v == '(' {
      count++
    } else if v == ')' {
      count--
      if count < 0 {
        return false
      }
    }
  }
  return count == 0
}
type pair struct {
  count, cnt, idx int
  ss              string
}
func removeInvalidParentheses(s string) (result []string) {
  ans := 0
  n := len(s)
  mp := make(map[int][]string)
  mpSet := make(map[string]bool)
  vis := make(map[pair]bool)
  var dfs func(count, cnt, idx int, ss string) //count是左右括号匹配,cnt是还剩多少个字符
  dfs = func(count, cnt, idx int, ss string) {
    p := pair{count, cnt, idx, ss}
    if !vis[p] {
      vis[p] = true
    } else {
      return
    }
    if count == 0 && idx == n {
      if cnt > ans {
        ans = cnt
        mpSet[ss] = true
        mp[ans] = append(mp[ans], ss)
      } else if cnt == ans {
        if !mpSet[ss] {
          mp[ans] = append(mp[ans], ss)
          mpSet[ss] = true
        }
      }
    }
    if count < 0 || cnt == -1 || idx == n {
      return
    }
    //去除当前
    dfs(count, cnt-1, idx+1, ss)
    //不去除
    if s[idx] == '(' {
      count++
    } else if s[idx] == ')' {
      count--
    }
    dfs(count, cnt, idx+1, ss+string(s[idx]))
  }
  dfs(0, n, 0, "")
  //左右是否匹配 还剩多少个字符 idx现在到哪了 字符串
  for _, v := range mp[ans] {
    result = append(result, v)
  }
  return
}
目录
相关文章
|
2月前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
3月前
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
|
3月前
|
索引
力扣(LeetCode)数据结构练习题(3)------链表
力扣(LeetCode)数据结构练习题(3)------链表
107 0
|
3月前
力扣(LeetCode)数据结构练习题(2)
力扣(LeetCode)数据结构练习题(2)
35 0
|
3月前
|
存储
力扣(LeetCode)数据结构练习题
力扣(LeetCode)数据结构练习题
64 0
|
4月前
|
Go
Golang语言之管道channel快速入门篇
这篇文章是关于Go语言中管道(channel)的快速入门教程,涵盖了管道的基本使用、有缓冲和无缓冲管道的区别、管道的关闭、遍历、协程和管道的协同工作、单向通道的使用以及select多路复用的详细案例和解释。
152 4
Golang语言之管道channel快速入门篇
|
4月前
|
Go
Golang语言文件操作快速入门篇
这篇文章是关于Go语言文件操作快速入门的教程,涵盖了文件的读取、写入、复制操作以及使用标准库中的ioutil、bufio、os等包进行文件操作的详细案例。
76 4
Golang语言文件操作快速入门篇
|
4月前
|
Go
Golang语言之gRPC程序设计示例
这篇文章是关于Golang语言使用gRPC进行程序设计的详细教程,涵盖了RPC协议的介绍、gRPC环境的搭建、Protocol Buffers的使用、gRPC服务的编写和通信示例。
125 3
Golang语言之gRPC程序设计示例
|
4月前
|
安全 Go
Golang语言goroutine协程并发安全及锁机制
这篇文章是关于Go语言中多协程操作同一数据问题、互斥锁Mutex和读写互斥锁RWMutex的详细介绍及使用案例,涵盖了如何使用这些同步原语来解决并发访问共享资源时的数据安全问题。
105 4
|
4月前
|
Go 调度
Golang语言goroutine协程篇
这篇文章是关于Go语言goroutine协程的详细教程,涵盖了并发编程的常见术语、goroutine的创建和调度、使用sync.WaitGroup控制协程退出以及如何通过GOMAXPROCS设置程序并发时占用的CPU逻辑核心数。
92 4
Golang语言goroutine协程篇