[路飞]_LeetCode题1249移除无效的括号

151 阅读1分钟

题目描述

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

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

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

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

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

示例 1:

输入:s = "lee(t(c)o)de)" 输出:"lee(t(c)o)de" 解释:"lee(t(co)de)" , "lee(t(c)ode)" 也是一个可行答案。 示例 2:

输入:s = "a)b(c)d" 输出:"ab(c)d" 示例 3:

输入:s = "))((" 输出:"" 解释:空字符串也是有效的 示例 4:

输入:s = "(a(b(c)d)" 输出:"a(b(c)d)"  

提示:

1 <= s.length <= 10510^5 s[i] 可能是 '('、')' 或英文小写字母

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/mi… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解思路

  1. 遍历s。
  2. 遇到字母原样记录。
  3. 发现"("则原样记录,并向left中记录其在原字符串中的位置。
  4. 发现")",并且left中有未配对的"(",则记录")",并pop出left栈顶的"("位置。
  5. 其他情况不需要记录。
  6. 循环完成后我们得到的是带所有有效的")"以及所有的"("。
  7. 此时需要排查left中是否存在无效的"("。
  8. 存在无效的左括号我们就再次依据left存储的位置信息对无效位的"("进行删除。
  9. 最后得到的就是没有无效括号的字符串。

题解代码

 * @lc app=leetcode.cn id=1249 lang=javascript
 *
 * [1249] 移除无效的括号
 */

// @lc code=start
/**
 * @param {string} s
 * @return {string}
 */
var minRemoveToMakeValid = function(s) {
  let res = "";
  let left = [];//字符串中所有未找到匹配的左括号
  for (let i = 0; i < s.length; i++) {
    //1.字母时候直接原样记录
    //2.发现"("则原样记录,并向left中记录其在源字符串中的位置
    //3.发现")",并且left中有未配对的"(",则记录")",并pop出left栈顶的"("位置
    //4.其他情况不需要记录
    if (s[i] !== "(" && s[i] !== ")") {
      res += s[i];
    }else if (s[i] === "(") {
      res += s[i];
      left.push(res.length - 1);
    }else if (s[i] === ")" && left.length > 0) {
      left.pop();
      res += s[i];
    }
  }
  
  //此时res得到的是带所有有效的")"以及所有的"(",
  //此时需要排查left中是否存在无效的"("
  //存在无效的左括号我们就再次依据left存储的位置信息对无效位的"("进行删除
  //最后得到的就是没有无效括号的字符串
  if (left.length > 0) {
    let delStr = "";
    for (let i = 0; i < res.length; i++) {
      if (left[0] === undefined || i !== left[0]) {
        delStr += res[i]
      }else{
        left.shift();
      }
    }
    res = delStr;
  }
  return res;
};
// @lc code=end