Balanced Substring—前缀和与差分(思维)

4 篇文章 0 订阅
You are given a string s consisting only of characters 0 and 1. A substring [l, r] of s is a string slsl + 1sl + 2... sr, and its length

equals to r - l + 1. A substring is called balanced if the number of
zeroes (0) equals to the number of ones in this substring.

You have to determine the length of the longest balanced substring of s. Input

The first line contains n (1 ≤ n ≤ 100000) — the number of characters in s.

The second line contains a string s consisting of exactly n characters. Only characters 0 and 1 can appear in s. Output

If there is no non-empty balanced substring in s, print 0. Otherwise, print the length of the longest balanced substring.

Examples
Input

8
11010111

Output

4

Input

3
111

Output

0

Note

In the first example you can choose the substring [3, 6]. It is balanced, and its length is 4. Choosing the substring [2, 5] is also

possible.

In the second example it's impossible to find a non-empty balanced substring.

题解:
一开始用的暴力算法,果不其然,超时了
后来才知道这是一道前缀和的思维题,将0看作-1,将1看成1,实现过程就是从头到尾扫一遍,每次更新前缀和,若该前缀和已经出现过,当前位置与第一次出现的位置做差,利用这段差区间的长度去更新结果,扫的过程同时要记录每个前缀和最早出现的位置。

#include<iostream>
using namespace std;
int a[100005];
int sum[100005];
int main()
{
    std::ios::sync_with_stdio(false);
    int n;
    cin>>n;
    string s;
    cin>>s;
    for(int i=0;i<n;i++)
    {
        if(s[i]=='0')a[i+1]=-1;
        if(s[i]=='1')a[i+1]=1;
    }
    for(int i=1;i<=n;i++)
    {
        sum[i]=sum[i-1]+a[i];
    }
    int k=n,flag=0;
    while(k!=0&&flag==0)
    {
        for(int i=n;i-k>=0;i--)
        {
            if((sum[i]-sum[i-k])==0)
            {
                cout<<k<<endl;
                flag=1;
                break;
            }
        }
        k--;
    }
    if(flag==0)cout<<0<<endl;
    
}

这次是正确代码,有用到map

#include<iostream>
#include<map>
using namespace std;
const int N=1e5+10;
map<int,int>ind;
char s[N];
int n;
int main()
{
    cin>>n;
    scanf("%s",s+1);
    int len=0,sum=0;
    ind[0]=0;
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='1')sum++;
        else sum--;
        if(ind.find(sum)==ind.end())ind[sum]=i;
        else len=max(len,i-ind[sum]);
    }
    cout<<len<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值