• 【LeetCode】301.删除无效的括号


    题目

    给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。

    返回所有可能的结果。答案可以按 任意顺序 返回。

    示例 1:

    输入:s = "()())()"
    输出:["(())()","()()()"]
    

    示例 2:

    输入:s = "(a)())()"
    输出:["(a())()","(a)()()"]
    

    示例 3:

    输入:s = ")("
    输出:[""]
    

    提示:

    • 1 <= s.length <= 25
    • s 由小写英文字母以及括号 '(' 和 ')' 组成
    • s 中至多含 20 个括号

    解答

    源代码

    1. class Solution {
    2. List res;
    3. public List removeInvalidParentheses(String s) {
    4. res = new ArrayList<>();
    5. int lremove = 0, rremove = 0;
    6. for (char c : s.toCharArray()) {
    7. if (c == '(') {
    8. lremove++;
    9. } else if (c == ')') {
    10. if (lremove > 0) {
    11. lremove--;
    12. } else {
    13. rremove++;
    14. }
    15. }
    16. }
    17. func(s, 0, lremove, rremove);
    18. return res;
    19. }
    20. public void func(String str, int start, int lremove, int rremove) {
    21. // 没有需要去掉的左右括号了
    22. if (lremove == 0 && rremove == 0) {
    23. if (isValid(str)) {
    24. res.add(str);
    25. }
    26. return;
    27. }
    28. for (int i = start; i < str.length(); i++) {
    29. if (i != start && str.charAt(i) == str.charAt(i - 1)) {
    30. continue;
    31. }
    32. // 剩余的字符数量小于需要去掉的括号数,那就不符合,直接返回
    33. if (lremove + rremove > str.length() - i) {
    34. return;
    35. }
    36. if (lremove > 0 && str.charAt(i) == '(') {
    37. func(str.substring(0, i) + str.substring(i + 1), i, lremove - 1, rremove);
    38. }
    39. if (rremove > 0 && str.charAt(i) == ')') {
    40. func(str.substring(0, i) + str.substring(i + 1), i, lremove, rremove - 1);
    41. }
    42. }
    43. }
    44. public boolean isValid(String str) {
    45. int count = 0;
    46. for (char c : str.toCharArray()) {
    47. if (c == '(') {
    48. count++;
    49. } else if (c == ')') {
    50. count--;
    51. if (count < 0) {
    52. return false;
    53. }
    54. }
    55. }
    56. return count == 0;
    57. }
    58. }

    总结

    我们可以使用回溯算法,尝试遍历所有可能的去掉非法括号的方案。

    先对原字符串进行统计,得到需要去掉的左右括号数量。然后我们尝试在原字符串中去掉这些数量的左右括号,检测剩余的字符串是否合法匹配,如果合法匹配则我们则认为该字符串为可能的结果,我们利用回溯算法来尝试搜索所有可能的去除括号的方案。

    当需要去掉的左右括号的数量都为0时,判断此时的字符串是否匹配,若匹配则记录下来。

    剩余字符数量小于当前左右括号数量时,可以直接判断字符串不符合,返回。

    为了避免得到重复的结果,我们在每次进行搜索时,如果遇到连续相同的括号我们只需要搜索一次即可,比如当前遇到的字符串为 "(((())",去掉前四个左括号中的任意一个,生成的字符串是一样的,均为 "((())",因此我们在尝试搜索时,只需去掉一个左括号进行下一轮搜索,不需要将前四个左括号都尝试一遍。

  • 相关阅读:
    css word-spacing test 2208100255
    odoo 开发入门教程系列-模型之间的关系(Relations Between Models)
    【算法】数组中出现次数超过一半的数字
    Notepad-- 轻量级文本编辑器的安装及基本使用
    pycharm的debug,你知道每个按钮对应哪个功能吗?
    ubuntu下cups部分场景
    基于工业互联网标识解析的数字化治理研究
    WebGL:使用着色器进行几何造型
    网络精通-DHCP
    基于elelemt-ui封装一个表单
  • 原文地址:https://blog.csdn.net/qq_57438473/article/details/132710765