B. 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
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构成的字符串,让你在该字符串中找出最长的平衡子串。
题目分析:
题目意思很简单,但是要实现却需要些技巧。看到这题,首先想到用dp去解决,但是后来发现,前i项之间并没有明显的规律可循,于是想到动态规划中的前缀和思想,为了将dp数组的下标与其内容连起来,我们把s串中的 0 当成 -1 处理。
则我们可以得到:
if ( s [ i - 1 ] == 0) dp [ i ] = dp [ i - 1 ] - 1;
if ( s [ i - 1 ] == 1) dp [ i ] = dp [ i - 1 ] + 1;
那么接下来就简单了,我们只要记录出开始的位置,那么字串区间长度就可以等于 i 减去初始位置。这里我们要注意,因为我们的 0 用了 -1 来处理,所以我们的范围则变成了 - 1e6 ~ 1e6 ,我可以选择使用数组来记录初始位置,我们也可以使用map。
先来说,如果使用数组vis [ ] 的话,我们需要将数组开大一倍,并且设置一个数 MAX = 1e6 来处理数组中出现的负数,即 vis [ dp [ i ] + MAX ] ;
而我们如果用map来进行记录的话,可以直接定义一个map,而不需要浪费如此大的空间去存储,可以大大降低空间复杂度。
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
#include <stack>
#define maxn 2000005
#define INF 0x3f3f3f
using namespace std;
typedef long long ll;
int n;
char s[maxn];
int dp[maxn];
map<int, int> vis;
int main()
{
scanf("%d", &n);
memset(dp, 0, sizeof(dp));
scanf("%s", s);
for (int i = 1; i <= n; i++)
{
if (s[i - 1] == '0')
dp[i] = dp[i - 1] - 1;
if (s[i - 1] == '1')
dp[i] = dp[i - 1] + 1;
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (vis[dp[i]] == 0 && dp[i] != 0)
vis[dp[i]] = i;
else
ans = max(i - vis[dp[i]], ans);
}
/*
for(int i = 0; i <= n; i ++)
cout << dp[i] << ' ';
cout << endl;
for(int i = 0; i <= n; i ++)
cout << vis[i] << ' ';
cout << endl;
*/
cout << ans << endl;
//system("pause");
return 0;
}
/*
0 1 2 3 4 5 6 7 8
1 1 0 1 0 1 1 1
0 1 2 1 2 1 2 3 4
0 1 2 1 2 1 2 7 8
*/