• 括号相关问题


    20. 有效的括号

    labuladong 题解思路

    给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

    有效字符串需满足:

    1. 左括号必须用相同类型的右括号闭合。
    2. 左括号必须以正确的顺序闭合。
    3. 每个右括号都有一个对应的相同类型的左括号。

    示例 1:

    输入:s = "()"
    输出:true
    

    示例 2:

    输入:s = "()[]{}"
    输出:true
    

    示例 3:

    输入:s = "(]"
    输出:false
    

     思路:左括号进栈,遇到与栈顶元素相互匹配的右括号就出栈,最后如果栈空,则为有效的括号

    1. class Solution {
    2. public:
    3. bool isValid(string s) {
    4. stack<char> st;
    5. for(char c:s)
    6. {
    7. if(c== '(' || c== '[' || c== '{')//左括号入栈
    8. {
    9. st.push(c);
    10. }
    11. else
    12. {
    13. char changeTo=right(c);//将右括号转换成左括号
    14. //当st为空时,st.top()会报错,所以需要先判断st不为空,再用st.top()
    15. if(!st.empty()&&changeTo==st.top())//栈不为空且右括号和栈顶的左括号相匹配
    16. {
    17. st.pop();
    18. }
    19. else//不匹配
    20. {
    21. return false;
    22. }
    23. }
    24. }
    25. //若最后栈内的左括号全部出栈,则是有效的括号组合
    26. return st.empty();
    27. }
    28. char right(char c)
    29. {
    30. if(c==')')
    31. return '(';
    32. else if(c==']')
    33. return '[';
    34. else
    35. return '{';
    36. }
    37. };

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

    labuladong 题解思路

    只有满足下面几点之一,括号字符串才是有效的:

    • 它是一个空字符串,或者
    • 它可以被写成 AB (A 与 B 连接), 其中 A 和 B 都是有效字符串,或者
    • 它可以被写作 (A),其中 A 是有效字符串。

    给定一个括号字符串 s ,移动N次,你就可以在字符串的任何位置插入一个括号。

    • 例如,如果 s = "()))" ,你可以插入一个开始括号为 "(()))" 或结束括号为 "())))" 。

    返回 为使结果字符串 s 有效而必须添加的最少括号数

    示例 1:

    输入:s = "())"
    输出:1
    

    示例 2:

    输入:s = "((("
    输出:3

     思路:栈+用need表示需要插入的左括号数

    1. class Solution {
    2. public:
    3. int minAddToMakeValid(string s) {
    4. stack<int> st;
    5. int need=0;
    6. for(char c:s)
    7. {
    8. if(c=='(')
    9. {
    10. st.push(c);
    11. }
    12. else
    13. {
    14. if(!st.empty())
    15. {
    16. st.pop();
    17. }
    18. else
    19. {
    20. //插入一个左括号
    21. need++;
    22. }
    23. }
    24. }
    25. //左括号+右括号
    26. return need+st.size();
    27. }
    28. };

        这里不用栈也行,从左往右遍历s,遇到(时,leftCount加一,遇到)时,如果leftCount大于          0, 说明有左括号与之对应,leftCount减一;如果leftCount等于0,说明没有左括号对应了
        需要添加一个左括号,need加一;遍历结束后,如果leftCount还是大于0,说明缺少)
        与之对应,所以总共需要添加的括号数为leftCount+need。 

    1. class Solution {
    2. public:
    3. int minAddToMakeValid(string s) {
    4. int leftCount=0;
    5. int need=0;
    6. for(char c:s)
    7. {
    8. if(c=='(')
    9. {
    10. leftCount++;
    11. }
    12. else
    13. {
    14. if(leftCount>0)
    15. {
    16. leftCount--;
    17. }
    18. else
    19. {
    20. need++;
    21. }
    22. }
    23. }
    24. return need+leftCount;
    25. }
    26. };

    1541. 平衡括号字符串的最少插入次数

    labuladong 题解思路
    给你一个括号字符串 s ,它只包含字符 '(' 和 ')' 。一个括号字符串被称为平衡的当它满足:

    • 任何左括号 '(' 必须对应两个连续的右括号 '))' 。
    • 左括号 '(' 必须在对应的连续两个右括号 '))' 之前。

    比方说 "())", "())(())))" 和 "(())())))" 都是平衡的, ")()", "()))" 和 "(()))" 都是不平衡的。

    你可以在任意位置插入字符 '(' 和 ')' 使字符串平衡。

    请你返回让 s 平衡的最少插入次数。

    示例 1:

    输入:s = "(()))"
    输出:1
    解释:第二个左括号有与之匹配的两个右括号,但是第一个左括号只有一个右括号。我们需要在字符串结尾额外增加一个 ')' 使字符串变成平衡字符串 "(())))" 。

     思路:need代表对右括号的需求,res代表对左右括号配平的需求

    1. class Solution {
    2. public:
    3. int minInsertions(string s) {
    4. int need=0;//对右括号的需求
    5. int res=0;//对左、右括号配平的需求
    6. for(int i=0;isize();i++)
    7. {
    8. if(s[i]=='(')
    9. {
    10. //需要两个右括号
    11. need+=2;
    12. if(need%2==1)//需要的右括号数是奇数
    13. {
    14. //插入一个右括号,让它变成偶数
    15. res++;
    16. //对右括号的需求减一
    17. need--;
    18. }
    19. }
    20. else
    21. {
    22. need--;
    23. if(need==-1)//右括号不足(例:s=")")
    24. {
    25. //对右括号的需求为1
    26. need=1;
    27. //插入一个左括号
    28. res++;
    29. }
    30. }
    31. }
    32. return res+need;
    33. }
    34. };

    32. 最长有效括号 

    给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

    示例 1:

    输入:s = "(()"
    输出:2
    解释:最长有效括号子串是 "()"
    示例 2:

    输入:s = ")()())"
    输出:4
    解释:最长有效括号子串是 "()()"
    示例 3:

    输入:s = ""
    输出:0

    思路:DP+栈

    dp[i] 表示以s[i] 结尾的最长合法括号子串的长度。

    用栈来记录左括号的下标,这样遍历到右括号时,就能弹出栈顶元素,进行匹配。

    1. class Solution {
    2. public:
    3. int longestValidParentheses(string s) {
    4. int n=s.size();
    5. //dp[i]表示以s[i]结尾的最长合法括号子串的长度
    6. vector<int> dp(n);
    7. stack<int> st;
    8. for(int i=0;i
    9. {
    10. if(s[i]=='(')//以'('结尾的子串,必定不是合法括号
    11. {
    12. st.push(i);//左括号入栈
    13. dp[i]=0;
    14. }
    15. else//s[i]==')'
    16. {
    17. if(!st.empty())
    18. {
    19. int left=st.top();
    20. st.pop();
    21. if(left>0)
    22. dp[i]=dp[left-1]+i-left+1;//连续的有效括号
    23. else//left==0
    24. dp[i]=i-left+1;
    25. }
    26. else//没有匹配的左括号
    27. dp[i]=0;
    28. }
    29. }
    30. int res=0;
    31. for(int i=0;i
    32. res=max(res,dp[i]);
    33. return res;
    34. }
    35. };

  • 相关阅读:
    Games101笔记-计算机图形学概述
    分页文件pagefile.sys引出的疑问
    计算机图形学(七)-深度缓存、着色shadding、着色模型、着色频率、渲染管线
    Vue路由及Node.js环境搭建
    [21天学习挑战赛——内核笔记](六)——在debugfs中添加一个调试目录
    React中组件通信02——消息订阅与发布、取消订阅以及卸载组件时取消订阅
    面试:聊一聊 Java 数组默认的排序算法,我懵了
    通过竞品分析来挖掘产品卖点
    一个免杀项目分享
    Elasticsearch的使用
  • 原文地址:https://blog.csdn.net/weixin_50437588/article/details/126821660