[路飞]LeetCode-1249.移除无效的括号(你真的理解栈么?)

209 阅读1分钟

题目描述

给你一个由 '('')' 和小写字母组成的字符串 s

你需要从字符串中删除最少数目的 '(' 或者 ')' (可以删除任意位置的括号),使得剩下的「括号字符串」有效。

请返回任意一个合法字符串。

有效「括号字符串」应当符合以下 任意一条 要求:

  • 空字符串或只包含小写字母的字符串
  • 可以被写作 ABA 连接 B)的字符串,其中 A 和 B 都是有效「括号字符串」
  • 可以被写作 (A) 的字符串,其中 A 是一个有效的「括号字符串」

思路分析

这道题是一道经典的思路的问题,常见的一种栈思路的问题解决方案可以用以下思路,定义一个变量num,正序遍历字符串,遇见左括号+1,遇见右括号-1。

当num < 0,则删除对应位置的右括号,一直到结束。

这时候我们已经将右括号处理完毕,左括号同理

逆序遍历对应字符串,遇见右括号+1,左括号-1

num < 0则删除对应左括号,

最终处理完毕。输出对应字符串值。

js实现如下

var minRemoveToMakeValid = function (s) {
    let num = 0;
    for (let i = 0; i < s.length; i++) {
        if (s[i] === "(") {
            num += 1;
        }
        if (s[i] === ")") {
            num -= 1;
        }

        if (num < 0 && (s[i] === "(" || s[i] === ")")) {
            num = 0;

            if (i === 0) {
                s = s.substring(1, s.length);
                i--;
                continue;
            }

            if (i === s.length - 1) {
                s = s.substring(0, i);
                continue;
            }

            s = s.substring(0, i) + s.substring(i + 1, s.length);
            i--;
        }
    }

    let len = s.length;
    let rightNum = 0;
    for (let j = len - 1; j >= 0; j--) {
        if (s[j] === ")") {
            rightNum += 1;
        }
        if (s[j] === "(") {
            rightNum -= 1;
        }

        if (rightNum < 0 && (s[j] === "(" || s[j] === ")")) {
            rightNum = 0;
            if (j === 0) {
                s = s.substring(1, s.length);
                continue;
            }
            if (j === s.length - 1) {
                s = s.substring(0, j);
                continue;
            }

            s = s.substring(0, j) + s.substring(j + 1, s.length);
        }
    }

    return s;
};

左加右减,一种非常经典的栈思路处理问题的方案。是入栈出栈的数学模拟实现。

学废了么?可以自己敲敲代码实现一下哦~~~