【问题标题】:Remove invalid parenthesis - JS (Leetcode301)删除无效括号 - JS (Leetcode 301)
【发布时间】:2021-08-11 12:53:10
【问题描述】:

我一直在接受 leetcode 挑战,遇到了一个有趣的问题:301. Remove Invalid Parentheses:

给定一个包含括号和字母的字符串s,删除最小数量的无效括号以使输入字符串有效。

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

示例 1:

Input: s = "()())()"
Output: ["(())()","()()()"]

示例 2:

Input: s = "(a)())()"
Output: ["(a())()","(a)()()"]

示例 3:

Input: s = ")("
Output: [""]

约束:

  • 1 <= s.length <= 25
  • s由小写英文字母和括号'('')'组成。
  • s 中最多有 20 个括号。

我尝试使用递归来解决它,但我的代码有问题,它返回一个空数组而不是结果。

代码如下:

var removeInvalidParentheses = function(s) {
  const validExpressions = [];
  let minimumRemoved = 0;
  function recurse(s, index, leftCount, rightCount, expression, removedCount) {
    let possibleAnswer;    
    if (index === s.length) {
      if (leftCount === rightCount) {
        if (removedCount <= minimumRemoved) {
          possibleAnswer = expression.join("");
          if (removedCount < minimumRemoved) {
            validExpressions.length = 0;
            minimumRemoved = removedCount;
          }
          validExpressions.push(possibleAnswer);
        }
      }
    } else {
      let currentCharacter = s[index];
      let length = expression.length;
      if (currentCharacter !== '(' && currentCharacter !== ')') {
        expression.push(currentCharacter);
        recurse(s, index + 1, leftCount, rightCount, expression, removedCount);
        expression.splice(length, 1);
      } else {
        recurse(s, index + 1, leftCount, rightCount, expression, removedCount + 1);
        expression.push(currentCharacter);
        if (currentCharacter == '(') {
          recurse(s, index + 1, leftCount + 1, rightCount, expression, removedCount);
        } else if (rightCount < leftCount) {
          recurse(s, index + 1, leftCount, rightCount + 1, expression, removedCount);
        }
        expression.splice(length, 1);
      }
    }
  }
  recurse(s, 0, 0, 0, [], 0);
  return validExpressions;
}

【问题讨论】:

    标签: javascript string algorithm


    【解决方案1】:

    问题是你初始化了minimumRemoved = 0,这使得不可能永远满足条件if (removedCount &lt;= minimumRemoved) {,除非removeCount为0。但如果在那个条件下没有匹配,什么都不会被推送到@987654325 @。

    你会想模仿可能的最坏情况,这样任何解决方案都会被认为比这更好。因此将 removedCount 初始化为一个大数字,例如 s.length + 1 或 -- 为什么不 -- Infinity

    您的代码中还有第二个问题:它可能会在 validExpressions 中收集重复值,因此请像这样编写您的 return 语句:

    return [...new Set(validExpressions)];
    

    这将使它工作。现在,这不是一个非常快速的解决方案。您可能想尝试寻找改进。

    【讨论】:

    • 谢谢,我刚刚发现了这两个问题,来这里回答我自己的问题。你是对的,这确实是一个非常缓慢的解决方案,我真的不明白如何改进它。而且我不确定时间复杂度,但我认为它一定是指数级的。
    • 我问,你是如何形成这样的问题的 - simplest-image-hosting-net.s3.ap-southeast-2.amazonaws.com/… ???
    • 您可以单击问题下方的编辑链接,您将看到我使用的格式代码。注意:编辑器有一些工具栏按钮可以帮助您进行此类格式化。
    • 我下次用。非常感谢。
    【解决方案2】:

    trincot 正确地突出了这些问题。这是最终代码:

    let removeInvalidParentheses = function (s) {
        const validExpressions = [];
        let minimumRemoved = Number.MAX_SAFE_INTEGER;
    
        function recurse(
            s,
            index,
            leftCount,
            rightCount,
            expression,
            removedCount
        ) {
            let possibleAnswer;
    
            // If we have reached the end of string.
            if (index === s.length) {
                // If the current expression is valid.
                if (leftCount === rightCount) {
                    // If the current count of removed parentheses is <= the current minimum count
                    if (removedCount <= minimumRemoved) {
                        // Convert StringBuilder to a String. This is an expensive operation.
                        // So we only perform this when needed.
                        possibleAnswer = expression.join("");
    
                        // If the current count beats the overall minimum we have till now
                        if (removedCount < minimumRemoved) {
                            validExpressions.length = 0;
                            minimumRemoved = removedCount;
                        }
                        validExpressions.push(possibleAnswer);
                    }
                }
            } else {
                let currentCharacter = s[index];
                let length = expression.length;
    
                // If the current character is neither an opening bracket nor a closing one,
                // simply recurse further by adding it to the expression StringBuilder
                if (currentCharacter !== "(" && currentCharacter !== ")") {
                    expression.push(currentCharacter);
                    recurse(
                        s,
                        index + 1,
                        leftCount,
                        rightCount,
                        expression,
                        removedCount
                    );
                    expression.splice(length, 1);
                } else {
                    // Recursion where we delete the current character and move forward
                    recurse(
                        s,
                        index + 1,
                        leftCount,
                        rightCount,
                        expression,
                        removedCount + 1
                    );
                    expression.push(currentCharacter);
    
                    // If it's an opening parenthesis, consider it and recurse
                    if (currentCharacter == "(") {
                        recurse(
                            s,
                            index + 1,
                            leftCount + 1,
                            rightCount,
                            expression,
                            removedCount
                        );
                    } else if (rightCount < leftCount) {
                        // For a closing parenthesis, only recurse if right < left
                        recurse(
                            s,
                            index + 1,
                            leftCount,
                            rightCount + 1,
                            expression,
                            removedCount
                        );
                    }
    
                    // Undoing the append operation for other recursions.
                    expression.splice(length, 1);
                }
            }
        }
    
        recurse(s, 0, 0, 0, [], 0);
        return Array.from(new Set(validExpressions));
    };
    

    【讨论】:

      猜你喜欢
      • 2018-01-14
      • 2018-11-07
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2023-01-28
      • 1970-01-01
      • 1970-01-01
      • 2015-09-13
      相关资源
      最近更新 更多