使括号有效的最少添加

114 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情

[921. 使括号有效的最少添加]

leetcode.cn/problems/mi…

image-20221004100029820


简单来说:题目的意思就是给一个括号字符串,问你需要补几个括号,能让整个字符串的括号匹配有效

  • 每个左括号必须对应一个右括号,而且左括号必须在对应的右括号之前

贪心:无论是哪种添加的情况,都是在遇到括号无法进行匹配的情况下才进行添加

做法1:使用栈

对于括号匹配的题目,常用的做法是使用栈进行匹配,栈具有后进先出的特点,因此可以保证右括号和最近的左括号进行匹配

做法: 用一个变量记录当前需要补充的左括号个数, 遍历字符串.

对于栈而言:如果碰到左括号,就直接进栈,如果碰到右括号,如果当前栈为空,就说明当前右括号是没有左括号和它匹配的,此时需要补充一个左括号

最后如果栈不为空,说明剩余的左括号没有与之匹配的右括号,此时需要添加对应的右括号, 所以需要添加的括号个数就是: 栈中剩余元素 + 需要补充的左括号个数

class Solution {
public:
    int minAddToMakeValid(string s) {
        stack<int> st;//左括号进栈,右括号就拿栈顶元素与之匹配
        int ans = 0;//记录需要补充的左括号个数
        for(auto& ch:s)
        {
            if(ch == '(')//左括号进栈
            {
                st.push(ch);
            }
            else
            {
                if(st.empty()) //如果当前栈为空,则说明需要添加左括号
                {
                    ans++;
                }
                else //弹出栈顶元素和当前右括号匹配
                {
                    st.pop();
                }
            }
        }
        return st.size() + ans;
    }
};

做法2:使用计数代替栈

进行匹配时每次都取距离当前位置最近的括号,就可以确保平衡

做法:从左到右遍历字符串,在遍历过程中维护左括号的个数以及定义一个变量记录需要添加的左括号次数

  • 如果遇到左括号,则将左括号的个数加 1

  • 如果遇到右括号,则需要和前面的左括号进行匹配

    • 如果左括号的个数大于 0,则说明前面有左括号可以匹配,因此将左括号的个数减 1,表示有一个左括号和当前右括号匹配
    • 如果左括号的个数等于 0, 则前面没有左括号可以匹配,需要添加一个左括号才能匹配,因此将添加次数加1

遍历结束后,需要检查左括号的剩余个数是否为0, 如果不为0,则说明还有剩下的左括号没有匹配,对于每个剩下的左括号都需要添加一个右括号才能匹配,此时需要添加的右括号个数为剩下的左括号个数

所以添加括号的数量就是: 最后剩余的左括号个数 + 需要添加的左括号次数


//给一个括号字符串,问你需要补几个括号,能让整个字符串的括号匹配有效
class Solution {
public:
    int minAddToMakeValid(string s) {
        int count = 0;//左括号的个数      -> 需要多少个右括号和它匹配
        int ans = 0;//需要添加的左括号
        for(int i = 0;i<s.size();i++)
        {
            if(s[i] == '(')
                count++;
            else    //当前是右括号
            {
                if(count>0) //如果前面有左括号
                    count--; //拿一个左括号和当前的右括号匹配
                else    //前面没有左括号
                    ans++; //此时需要在前面添加1个左括号和当前的右括号匹配
            }
        }
        //最少的添加括号=剩余的左括号个数(没有右括号和它匹配)+需要添加的左括号
        return ans + count;
    }
};