文章目录

  • 题目描述
  • 思路 && 代码
    • 二刷

题目描述

  • 【所有可能结果】-> 【暴力DFS】

思路 && 代码

  • 代码比较长,但是总体思路很清晰。
  • 剪枝:舍弃左括号、舍弃右括号两种情况(见注释)
  • 分情况:当前字符有【左括号】、【右括号】、【字母】三种情况,字母直接取,不影响
  • 具体见注释的 Case 分类,有清晰说明
  • 去重:先通过 Set 存储所有当前可行解
  • 筛选:dfs结束后,len 为删除最小数量无效括号后的字符串长度。用于对 Set 中的有效括号进行筛选。
class Solution {int len; // 维护有效字符串的最长值public List<String> removeInvalidParentheses(String s) {char[] arr = s.toCharArray();int right = 0;// 右括号计数:用于 dfs 剪枝(选取左括号数量,一定不能大于右括号数量)for(char c : arr) {if(c == ')') {right++;}}// Set 用于去重Set<String> set = new HashSet<>();dfs(arr, 0, 0, right, new StringBuilder(), set);List<String> ans = new ArrayList<>();for(String str : set) {// 筛选if(str.length() == len) {ans.add(str);}}return ans;}public void dfs(char[] cs, int index, int score, int max, StringBuilder cur, Set<String> ans) {// Case 1: 结束if(index == cs.length) {// 合法,并且长度够的情况if(score == 0 && cur.length() >= len) {// 加入 Set 中,并且维护 lenlen = cur.length();ans.add(cur.toString());}return;}// Case 2:当前为左括号if(cs[index] == '(') {// Case 2.1:选择【加入】当前左括号(如果 score + 1 > max,说明后面右括号【肯定】不够了)if(score + 1 <= max) {dfs(cs, index + 1, score + 1, max, cur.append('('), ans);cur.deleteCharAt(cur.length() - 1);}// Case 2.2:选择【不加入】当前左括号dfs(cs, index + 1, score, max, cur, ans);}// Case 3:当前为右括号else if(cs[index] == ')') {// Case 3.1:选择【加入】当前右括号(左边有提供左括号)if(score > 0) {dfs(cs, index + 1, score - 1, max, cur.append(')'), ans);cur.deleteCharAt(cur.length() - 1);}// Case 3.2:选择【不加入】当前右括号dfs(cs, index + 1, score, max, cur, ans);}// Case 4:当前为字母,直接【加入】,不影响else {dfs(cs, index + 1, score, max, cur.append(cs[index]), ans);cur.deleteCharAt(cur.length() - 1);}}
}
  • 无注释版
class Solution {int len; public List<String> removeInvalidParentheses(String s) {char[] arr = s.toCharArray();int right = 0;for(char c : arr) {if(c == ')') {right++;}}Set<String> set = new HashSet<>();dfs(arr, 0, 0, right, new StringBuilder(), set);List<String> ans = new ArrayList<>();for(String str : set) {if(str.length() == len) {ans.add(str);}}return ans;}public void dfs(char[] cs, int index, int score, int max, StringBuilder cur, Set<String> ans) {if(index == cs.length) {if(score == 0 && cur.length() >= len) {len = cur.length();ans.add(cur.toString());}return;}if(cs[index] == '(') {if(score + 1 <= max) {dfs(cs, index + 1, score + 1, max, cur.append('('), ans);cur.deleteCharAt(cur.length() - 1);}dfs(cs, index + 1, score, max, cur, ans);}else if(cs[index] == ')') {if(score > 0) {dfs(cs, index + 1, score - 1, max, cur.append(')'), ans);cur.deleteCharAt(cur.length() - 1);}dfs(cs, index + 1, score, max, cur, ans);}else {dfs(cs, index + 1, score, max, cur.append(cs[index]), ans);cur.deleteCharAt(cur.length() - 1);}}
}

二刷

  • 二刷懵逼的地方:合法性维护

    1. 靠 score 来进行,众所周知 ‘(’ 随便加,等跑到结尾再算帐 (score == 0)
    2. 但 ‘)’ 不一样,得前面的 ‘(’ 数量够才行。( if(score > 0) )
    3. 由此上两点,可得出合法判断
  • 【选出合法结果,维护最长合法长度】-》【由最终长度,筛选较小结果】
  • 来了,无剪枝,无效率优化的写法!咱图的就是一个简单明了!摆烂,慢得一
  • 具体是少了 StringBuilder、char[] 等优化,但有效代码就 22 行,很简约!
class Solution {int maxLen = 0;Set<String> set = new HashSet<>();public List<String> removeInvalidParentheses(String s) {dfs(0, 0, "", s);List<String> ans = new ArrayList<>();for(String temp : set) {if(temp.length() == maxLen) {ans.add(temp);}}return ans;}void dfs(int score, int index, String now, String s) {if(index == s.length()) {if(score == 0 && now.length() >= maxLen) {maxLen = now.length();set.add(now);} }else if(s.charAt(index) == '(') {dfs(score + 1, index + 1, now + '(', s);dfs(score, index + 1, now, s);}else if(s.charAt(index) == ')') {if(score > 0) {dfs(score - 1, index + 1, now + ')', s);}dfs(score, index + 1, now, s);}else {dfs(score, index + 1, now + s.charAt(index), s);}}
}

【LeetCode笔记】301. 删除无效的括号(Java、DFS、字符串)相关推荐

  1. 【LeetCode】【HOT】301. 删除无效的括号(递归)

    [LeetCode][HOT]301. 删除无效的括号 文章目录 [LeetCode][HOT]301. 删除无效的括号 package hot;import java.util.ArrayList; ...

  2. LeetCode 301. 删除无效的括号(回溯)

    文章目录 1. 题目 2. 解题 1. 题目 删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果. 说明: 输入可能包含了除 ( 和 ) 以外的字符. 示例 1: 输入: "( ...

  3. Leecode 301. 删除无效的括号——Leecode每日一题系列

    题目描述 给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效. 返回所有可能的结果.答案可以按 任意顺序 返回. 示例 1: 输入:s = "()()) ...

  4. 301 Remove Invalid Parentheses 删除无效的括号

    删除最小数目的无效括号,使输入的字符串有效,返回所有可能的结果. 注意: 输入可能包含了除 ( 和 ) 以外的元素. 示例 : "()())()" -> ["()( ...

  5. 【LeetCode笔记】20.有效的括号(Java、栈) 21. 合并两个有序链表(Java)

    文章目录 20. 题目描述 & 解题 21. 题目描述 & 解题 1. 一开始的写法 2. 参考大佬的写法 两道简单类型连着,就直接一起写了. 20. 题目描述 & 解题 括号 ...

  6. LeetCode 1249. 移除无效的括号(栈+set / deque)

    1. 题目 给你一个由 '('.')' 和小写字母组成的字符串 s. 你需要从字符串中删除最少数目的 '(' 或者 ')' (可以删除任意位置的括号),使得剩下的「括号字符串」有效. 请返回任意一个合 ...

  7. 【LeetCode笔记】253. 会议室 II(Java、偏数学)

    文章目录 题目描述 思路 && 代码 计划里 hot 100 + 剑指Offer 的题目中唯一一道会员题,同时也是最后一道没写的题,刚好今天 leetcode 发了一天会员可以写上-简 ...

  8. 【LeetCode笔记】162. 寻找峰值(Java、二分、偏数学)

    文章目录 题目描述 思路 && 代码 1. 暴力法 O(n) 2. 二分法 O(logN) 二刷 打卡第十七天- 题目描述 难点在于 logN 复杂度 思路 && 代码 ...

  9. 【LeetCode笔记】221. 最大正方形(Java、动态规划、思路题)

    文章目录 题目描述 思路 & 代码 更新版 题目描述 显而易见地可以用dp来写,问题在于如何考虑状态转移方程 思路 & 代码 首先再加一层外墙,就不用边界判断了 maxSqure[i] ...

最新文章

  1. 一个小需求,能够做到月活跃用户5000万,就是真牛逼!
  2. Curr Biol:间隔学习可巩固记忆的奥秘
  3. 彻底颠覆神经科学?神经信号可能不是电信号,而是机械波?!
  4. 1.18 Java直接插入排序法
  5. 特性,物料特性,批次特性(转自SAPNow)
  6. Microsoft SQL Server 2008技术内幕:T-SQL查询---------查询优化
  7. python选择题题库for、if_Python题目1:猜年龄(for、if else和where)
  8. python 常用模块函数_python函数和常用模块(三),Day5
  9. 英语四级关于计算机阅读理解,英语四级阅读模拟训练附答案和精讲 第6篇:学习计算机...
  10. sci的figure怎么做_如何制作科技论文中的Figure
  11. JavaWeb项目开发案例精粹-第6章报价管理系统-001需求分析及设计
  12. 如何在 Mac 上自定 Safari 浏览器窗口?
  13. 19. JavaScript RegExp 对象
  14. python_列表_常用操作
  15. ubuntu修改默认root密码
  16. 解决window10播放.avi格式视频黑屏,只有声音没有视频0xc00d5212错误
  17. python读取地震信号【sgy,segy】
  18. 配置系统未能初始化 错误的解决方案
  19. RT-Thread Studio ulog日志
  20. DNS 的A name和C name的区别

热门文章

  1. session的钝化和活化
  2. 对于JDBC的简单理解
  3. html 点击div 改变高度,HTML / CSS将div设置为同级的高度
  4. 技术面试问项目难题如何解决的_技术创新 | 降本增效,青海农信社项目小伙刻苦钻研解决联合支架设计难题!...
  5. 英语计算机房和操场怎么读,计算机房对我们学习帮助很大. the , in studies , computer , room , helps , lot , a , our , us...
  6. oracle 根据分隔符提取,oracle使用指定分隔符导出数据到文件
  7. React之JSX入门
  8. Ubuntu 防火墙 ufw
  9. Spring Data JPA 从入门到精通~JpaSpecificationExecutor的使用方法
  10. java web响应式框架_Web开发的十佳HTML5响应式框架