• 301. Remove Invalid Parentheses


    问题:

    给定一个字符串,包含左右小括号+字母。

    对该字符串进行【括号删减】,使得 字符串中括号完全匹配。"( )"

    求最少删减字符,能得到的所有完全匹配的字符串。

    Example 1:
    Input: "()())()"
    Output: ["()()()", "(())()"]
    
    Example 2:
    Input: "(a)())()"
    Output: ["(a)()()", "(a())()"]
    
    Example 3:
    Input: ")("
    Output: [""]
    

      

    解法:Backtracking(回溯算法)

    前期准备:

    遍历字符串,遇到"(" count++,遇到")" count--

    那么匹配的正常字符串的count变化应该总是符合:count>=0....最终count==0

    若期间只要有count<0,那么这时一定多余出来一个")"

    计算这样多余出来的")"的个数:minright

    去掉这些不符合条件的")",最后,得到count>0,则为多出来的"(",计数为minleft

    Backtracking:

    状态:

    • 到目前位置pos为止,删减括号,得到的正确字符串path。
    • 这时,剩下可删减的"("个数:left
    • 剩下可删减的")"个数:right
    • 当前的count状态,由于path为正确字符串,那么count一定>=0,若<0,则不符合要求,直接返回。

    选择:

    • 当前字符:s[pos]
      • "(" 且 还可删减 left>0:对s[pos]删除:path, count, left--, right
      • ")" 且 还可删减 right>0:对s[pos]删除:path, count, left, right--
    • 不删减:若s[pos]:path+s[pos], count(做以下处理), left, right
      • "(" :count++
      • ")" :count--

    递归退出条件:

    • pos==s.length
      • 若left==right==count==0 则 res.push_back(path),再return
      • 否则直接return
    • 若count<0, 直接return。当前path已经不满足括号匹配要求。

    代码参考:

     1 class Solution {
     2 public:
     3    // int cc = 0;
     4    // void print_intend() {
     5    //     for(int i=0; i<cc; i++) {
     6    //         printf("  ");
     7    //     }
     8    // }
     9     void backtrack(unordered_set<string>& res, string path, int pos, int count, int left, int right, string& s) {
    10         if(count<0) return;
    11         if(pos==s.length()) {
    12             if(left==0 && right==0 && count==0) {
    13                 res.insert(path);
    14     //            print_intend();
    15     //            printf("return res.last:%s.
    ", path.c_str());
    16             }
    17             return;
    18         }
    19         if(s[pos]=='(' && left>0) {
    20     //        print_intend();
    21     //        printf("count:%d, left:%d, right:%d. path:%s
    ", count, left-1, right, path.c_str());
    22      //       cc++;
    23             backtrack(res, path, pos+1, count, left-1, right, s);
    24      //       cc--;
    25         } else if(s[pos]==')' && right>0) {
    26     //        print_intend();
    27     //        printf("count:%d, left:%d, right:%d. path:%s
    ", count, left, right-1, path.c_str());
    28      //       cc++;
    29             backtrack(res, path, pos+1, count, left, right-1, s);
    30      //       cc--;
    31         }
    32         switch(s[pos]) {
    33             case '(': count++; break;
    34             case ')': count--; break;
    35             default: break;
    36         }
    37     //        print_intend();
    38     //        printf("--count:%d, left:%d, right:%d. path:%s
    ", count, left, right, path.c_str());
    39     //    cc++;
    40         backtrack(res, path+s[pos], pos+1, count, left, right, s);
    41     //    cc--;
    42         return;
    43     }
    44     vector<string> removeInvalidParentheses(string s) {
    45         unordered_set<string> res;
    46         string path;
    47         int minleft = 0, minright = 0, count = 0;
    48         for(char c:s) {
    49             switch(c) {
    50                 case '(': count++; break;
    51                 case ')': count--; break;
    52                 default: break;
    53             }
    54             if(count<0) {
    55                 minright++;//')'
    56                 count++;
    57             }
    58         }
    59         minleft=count;//'('
    60         backtrack(res, path, 0, 0, minleft, minright, s);
    61         return vector<string>(res.begin(), res.end());
    62     }
    63 };
  • 相关阅读:
    门面模式 Facade
    适配器模式 Adapter
    建造者模式 Builder Mode
    原型模式 ProtoType
    抽象工厂模式 Abstract Factory
    工厂方法模式 Factory Method
    简单工厂模式 SimpleFactory
    java设计模式之代理设计模式(Proxy)
    java工厂设计模式初步
    java中的接口概念
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14455132.html
Copyright © 2020-2023  润新知