有效的括号 + 点击消除 || 匹配问题

目录

点击消除: 

有效的括号: 


点击消除: 

点击消除_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/8d3643ec29654cf8908b5cf3a0479fd5?tpId=308&tqId=40462&ru=/exam/oj

如题目所述,

示例1:" abbc ",消除了相同且相邻的字母 b 后,剩下 " ac ", a 和 c 不是相邻的字母,最终结果为 " ac "

示例2:" abba ",消除了相同且相邻的字母 b 后,剩下 " aa ",消除 b 前不相邻的字母 a ,在消除后变相邻了,此时消除字母 a ,按照题目要求,最终输出结果为 0

我们可以借助栈后进先出的原理来解决这个问题:

假设 s 是输入的字符串,s[ i ] 是当前我们访问的字母,我们用字符串 result 来模仿栈,

1、当 result 为空,先把字母添加到 result 中,如图,此时把 a 添加到 result 中

2、当 result 不为空时,判断 result 的最后一个字符(相当于栈顶元素) 和 s[ i ] 是否为相等的字母,

a. 如果不相等,把字母 s[ i ] 添加到 result 中(相当于进栈),如图,假设 result 的栈顶元素为 a,s[ i ] 为 b,它们不相等,所以 b 进栈

b. 如果相等,说明栈顶元素和 s[ i ] 是相邻且相等的字母,栈顶元素和 s[ i ] 是要消除的字母,此时删除栈顶元素,完成了一次消除。如图,假设 result 的栈顶元素为 b,s[ i ] 为 b,它们相等且相邻,所以删除栈顶元素 b ,此时的栈顶元素变为 a。

根据上面的原理,再次来理解示例2:

i 从 0 开始:

s[ 0 ]:一开始栈为空,所以 a 进栈

s[ 1 ]:当访问字母 b 时,b 和栈顶元素 a 不相等,所以 b 进栈

s[ 2 ]:当访问字母 b 时,b 和栈顶元素 b 相等,所以 b 出栈

s[ 3 ]:当访问字母 a 时,a 和栈顶元素 a 相等,所以 a 出栈,此时 result 为空字符

用栈的思想就可以解决一开始相等但不相邻的字母,再经过消除后,变成相等且相邻的字母的消除问题。

#include <iostream>
using namespace std;
#include<string>
int main() {
   string enter;//接收输入的字符串
   cin>>enter;//输入
   string result;//最终结果的字符串,模拟栈
   for(int i=0;i<enter.size();i++)//遍历输入的字符串
   {
        //字符串不为空,且字符串的最后一个字符(即栈顶元素)和enter[i]字符相等
        if(result.size() && enter[i] == result.back())
        {
            result.pop_back();//消除字符串的最后一个字符,相当于出栈
        }
        else {
            //相当于进栈 
            result+=enter[i];
        }
   }
   if(result.size())
   {
        cout<<result<<endl;//字符串不为空
   }
   else {
        cout<<0<<endl;//字符串为空
   }
   return 0;
}

 

有效的括号: 

20. 有效的括号 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/valid-parentheses/submissions/525036077/

有效括号的匹配问题,需要处理三种匹配:

1、数量匹配,如果 s 中的括号个数为奇数个,则一定不匹配,直接利用库函数求出字符串的长度,长度为奇数,直接返回 false,如果 s 中的括号个数为偶数个,当左右括号的数量不匹配,返回 false

2、类型匹配() 匹配,{} 匹配,[] 匹配,否则都是属于不匹配

3、顺序匹配,必须先出现左括号,再出现右括号,比如 ) (,虽然都是小括号,但是先出现的是右括号,故不匹配

除此之外,类似上一题的点击消除,比如字符串为 " ( { [ ] } ) ”,消除了 [ ] 之后,字符串为 " ( { } ) ”,{ } 匹配,再次消除,字符串剩下 " (  ) ”, (  )匹配,所以整个字符串的括号都是匹配的

我们同样可以用栈的思想来解决问题:

1、如果访问的字符是左括号,则进栈

2、如果访问的字符是右括号

a. 如果栈为空,说明栈里面没有左括号,此时顺序不匹配,返回 false

b.如果栈不为空,则需要判断栈顶元素(左括号)和右括号是否匹配,如果左右括号匹配,则需要删除栈顶元素(因为这个栈顶元素的左括号已经有和它匹配的右括号了,不需要继续判断了),如果左右括号不匹配,直接返回 false

3、把所有的括号都判断完之后,并不意味着可以返回 true 了,如果栈不为空,说明左右括号的数量不匹配,返回 false,如果栈为空,说明所有的括号都匹配了,返回 true

class Solution {
public:
    bool isValid(string s) {
        stack<char> match;//存左括号
        if(s.size()%2!=0)
            return false;//单数个括号,数量不匹配
        for(int i=0;i<s.size();i++)
        {
            //左括号,进栈
            if(s[i]=='('||s[i]=='['||s[i]=='{')
            {
                match.push(s[i]);
            }   
            else
            {
                //右括号,且栈不为空,和栈顶元素匹配
                //不匹配,或者栈为空,false
                if(match.empty())
                    return false;
                if((s[i]==')' && match.top()!='(')
                || (s[i]==']' && match.top()!='[')
                || (s[i]=='}' && match.top()!='{'))
                    return false;
                
                match.pop();//匹配,删除栈顶元素
            } 
            
        }
       //s遍历完,且栈为空,true
       //栈不为空,false
       if(match.empty())
            return true;
        else
            return false;
    }
};

 

  • 17
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值