百度之星 括号

原题链接:码题集OJ-括号​​​​​​

题目大意:给一个由 '(' 和 ')' 构成的字符串,对于这个字符串可以最多翻转一个字符,让这个括号序列相互匹配,匹配是指从左到右,每一个左括号都能够对应一个右括号。问有几个可以翻转的位置?

思路:因为最多翻转一个位置,那么可以记录一下(的数量和)的数量,如果数量相等那么就是不用翻转的字符串,那么答案就是0。如果(的数量大于)的数量,那么就需要逆序的遍历字符串,因为能够消除)的括号一定在左边,如果遍历到了)那么就记录一下当前)的总和,如果是(那么如果)存在,那么答案就加一,并且)的数量减去1,如果)的数量为负数就跳出去。如果)的数量大于(就是同上面相反的思路。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pii;
const int N=1e6+10;
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	string s;cin>>s;
	ll sum1=0,sum2=0;
	for(auto i:s)
	{
		if(i=='(')sum1++;
		else sum2++;
	}
	ll ans=0,sum=0;
	/*
	sum为已经扫描过的字符串剩下的能够用来匹配的括号,当遇见相同的括号时数量加一,如果遇见了不同的括号,数量就会减去1。 
	如果sum>0,并且当前的括号和sum代表的括号不同,那么当前位置的括号就可以翻转。
	因为已经扫描过的字符串是不翻转匹配的,而且必须翻转一次,所以当前的位置可以翻转。
	到下一个位置的时候,将sum减一就代表之前扫描的位置为不翻转匹配的。
	如果sum为0,并且当前点的括号和sum代表的不同,那么当前点的括号就不能匹配,所以需要翻转。
	当这个位置之后,已经扫描的字符串就不是匹配的字符串了,之后再修改无法影响到之前的字符串,所以直接跳出 
	*/ 
	if(sum1>sum2)
	{ 
		for(int i=s.size()-1;i>=0;i--)
		{
			if(s[i]==')')sum++;
			else
			{
				ans++;
				if(sum==0)break;
				sum--;
			}
		}
	}
	else if(sum1<sum2)
	{
		for(int i=0;i<s.size();i++)
		{
			if(s[i]=='(')sum++;
			else 
			{
				ans++;
				if(sum==0)break;
				sum--;
			}
		}
	}
	cout<<ans;
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值