LeetCode每日一题(301. Remove Invalid Parentheses)

给定一个包含字母和括号的字符串,删除最小数量的无效括号使其变得有效。使用递归和哈希表存储不同长度的有效字符串,最终返回最长的有效结果并去重。

Given a string s that contains parentheses and letters, remove the minimum number of invalid parentheses to make the input string valid.

Return all the possible results. You may return the answer in any order.

Example 1:

Input: s = “()())()”
Output: [“(())()”,“()()()”]

Example 2:

Input: s = “(a)())()”
Output: [“(a())()”,“(a)()()”]

Example 3:

Input: s = “)(”
Output: [“”]

Constraints:

  • 1 <= s.length <= 25
  • s consists of lowercase English letters and parentheses ‘(’ and ‘)’.
  • There will be at most 20 parentheses in s.

遍历整个字符串, 每一个"(“或者”)“都有可能保留或者删除。我们对当前的字符串进行赋值以方便最终检查是否是合法的字符串, 遇到”(“值+1, 遇到”)“值-1, 最终合法的字符串的值必须为 0。要注意的是中途出现负值的情况, 我们必须舍弃当前的”)“, 因为一旦出现未匹配的”)",字符串一定是非法的。我们将每一个合法的字符串根据长度分组, 最终返回长度最长的那组即可。最后要注意的是最终结果要去重。



use std::collections::HashMap;

impl Solution {
    fn dp(chars: &Vec<char>, i: usize, curr_val: i32, mut curr_str: String, ans: &mut HashMap<usize, Vec<String>>) {
        if i == chars.len() {
            if curr_val == 0 {
                ans.entry(curr_str.len()).or_insert(Vec::new()).push(curr_str);
            }
            return;
        }
        let curr_char = chars[i];
        let next_val = if curr_char == '(' {
            curr_val + 1
        } else if curr_char == ')' {
            curr_val - 1
        } else {
            curr_val
        };
        if next_val < 0 {
            Solution::dp(chars, i + 1, curr_val, curr_str, ans);
            return;
        }
        let mut next_str = curr_str.clone();
        next_str.push(curr_char);
        Solution::dp(chars, i + 1, next_val, next_str, ans);
        Solution::dp(chars, i + 1, curr_val, curr_str, ans);
    }

    pub fn remove_invalid_parentheses(s: String) -> Vec<String> {
        let mut ans = HashMap::new();
        Solution::dp(&s.chars().collect(), 0, 0, "".into(), &mut ans);
        if let Some((_, mut v)) = ans.into_iter().max_by_key(|(k, _)| *k) {
            v.sort();
            v.dedup();
            v
        } else {
            vec!["".into()]
        }
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值