Balanced Substring

Balanced Substring

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

Input1
8
110101111
Output2
4
Input2
3
111
Output
0

题意:找出最长01子串使得0和1的数量一样。

比如input1:

输出4,对应的子串是

110101111

比如input2:

输出0,即没有01平衡串。

解题思路:

思路一:考虑区间dp的做法,使用二维矩阵bool arr[i][j]表示子串位置 i 到 j 是否为平衡串,其长度为j-i+1...........(略.....时间复杂度想想都不让过)

思路二:因为涉及到前缀和的问题,所以我们可以试试累加试试,结果没发现啥。

换个想法:试试把0设置为-1,1设置为1.

那么

1  1   0  1   0  1  1  1  1
1 1 -1 1 -1 1 1 1 1

求前缀和(第三行)

1  1   0  1   0  1  1  1  1
1 1 -1 1 -1 1 1 1 1
1 2 1 2 1 2 3 4 5

这里可以发现,最长平衡子串出现在下述两种情况

1  1   0  1   0  1  1  1  1
1 1 -1 1 -1 1 1 1 1
1 2 1 2 1 2 3 4 5
1 2 1 2 1 2 3 4 5

去掉最左边的前缀,其对应涂色的位置在原序列中即最长平衡子串。

故:

最长子串的位置出现在前缀和相同的位置之间,不妨设为L、R,最长平衡子串(L,R]。

Code

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#include<iostream>
int main(){
    int n;
    cin>>n;
    string str;
    cin>>str;
    int *sum=new int[str.length()+1];
    map<int ,int >mymap;
    sum[0]=0;
    mymap[0]=0;   //考虑整个串都是平衡串的因数
    for (int i = 0; i < n; i++){
        if(str[i]=='0')sum[i+1]=sum[i]-1;
        else
            sum[i+1]=sum[i]+1;
        if(mymap.find(sum[i])==mymap.end()){
            //记录每一个最早出现前缀和的位置
            mymap[sum[i]]=i;
        }
    }
    // for (int i = 0; i <= n; i++)
    // {
    //     cout<<sum[i]<<" ";
    // }
    // cout<<endl;
    // map<int,int>::iterator it=mymap.begin();
    // for ( map<int,int>::iterator it=mymap.begin(); it !=mymap.end(); it++)
    // {
    //     cout<<it->first<<" "<<it->second<<endl;
    // }
    // cout<<endl;
    int maxn=0;
    for (int i = 0; i <= n; i++){
        if(mymap.find(sum[i])!=mymap.end())
            maxn=max(maxn,i-mymap[sum[i]]);
        // cout<<"i= "<<i<<"  maxn="<<maxn<<endl;
    }   
    // cout<<endl;
    cout<<maxn<<endl;
    return 0;
}

 代码二:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    string str;
    cin>>n;
    cin>>str;
    map<int,int>q;
    int sum = 0,maxv = 0;
    for(int i = 0;i < n;i ++) {
        if(str[i] == '0')sum += -1;
        else sum += 1;
        if(!q[sum]&&sum)q[sum] = i + 1;//如果sum为0表示本来就平衡不需要标记了
        else{
            maxv = max(maxv,i - q[sum] + 1);
        }
    }
    cout<<maxv;
}

 

 

 

因上求缘,果上努力~~~~ 作者:每天卷学习,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/14280702.html

原文地址:https://www.cnblogs.com/BlairGrowing/p/14280702.html