1 和 0 数量相等的最长平衡二进制子串
给定一个大小为N的二进制字符串str[] 。任务是找到最长的平衡子串。如果子串包含相等数量的0和1 ,则它是平衡的。
例子:
Input: str = “110101010”
Output: 10101010
Explanation: The formed substring contain equal count of 1 and 0 i.e, count of 1 and 0 is same equal to 4.
Input: str = “0000”
Output: -1
天真的方法:一个简单的解决方案是使用两个嵌套循环来生成每个子字符串。第三个循环用于计算当前子字符串中0和1的数量。然后打印其中最长的子串。
时间复杂度: O(N^3)
辅助空间: O(1)
高效的解决方案:借助预计算,存储从开始到当前索引的0计数和1计数之间的差值。然后可以使用此差异来确定具有相等0s和1s的最长子字符串,作为差异数组中任何重复值之间的最长距离。使用基于 Map 的散列进行预计算。请按照以下步骤解决问题:
- 初始化地图
m[]。 - 将m[0]的值设置为-1。
- 初始化变量count_0、count_1、res、start和end 。
- 使用变量i遍历字符串str[]并执行以下任务:
- 将1和0的计数分别记录为count_1和count_0 。
- 查看count_1和count_0之间的当前差异是否已经存在于地图m[]中。如果是,则执行以下任务:
- 先前出现和当前索引的子字符串具有相同数量的0和1 。
- 如果当前找到的子字符串的长度大于res则将找到的子字符串设置为到目前为止的答案。
- 如果它是第一次出现,则将当前差值和当前索引存储在映射中,即m[count_1 – count_0]等于i 。
- 如果count_0和count_1都为0,则打印-1。
- 否则,从头到尾打印子字符串。
下面是上述方法的实现。
C++
// C++ for finding length
// of longest balanced substring
#include
using namespace std;
// Returns length of the longest substring
// with equal number of zeros and ones.
string stringLen(string str)
{
// Create a map to store differences
// between counts of 1s and 0s.
map m;
// Initially difference is 0.
m[0] = -1;
int count_0 = 0, count_1 = 0;
int start, end, res = 0;
for (int i = 0; i < str.size(); i++) {
// Keeping track of counts of
// 0s and 1s.
if (str[i] == '0')
count_0++;
else
count_1++;
// If difference between current counts
// already exists, then substring between
// previous and current index has same
// no. of 0s and 1s. Update result if this
// substring is more than current result.
if (m.find(count_1 - count_0) != m.end()) {
if ((i - m[count_1 - count_0]) > res) {
start = m.find(
count_1 - count_0)
->second;
end = i;
res = end - start;
}
}
// If current difference
// is seen first time.
else
m[count_1 - count_0] = i;
}
if (count_0 == 0 || count_1 == 0)
return "-1";
// Return the substring
// between found indices
return str.substr(start + 1, end + 1);
}
// Driver Code
int main()
{
string str = "110101010";
cout << stringLen(str);
return 0;
}
Java
// Java code for the above approach
import java.io.*;
class GFG
{
// Returns length of the longest substring
// with equal number of zeros and ones.
static String stringLen(String str)
{
// Create a map to store differences
// between counts of 1s and 0s.
int [] m = new int[100000];
// Initially difference is 0.
m[0] = -1;
int count_0 = 0; int count_1 = 0;
int start = 0; int end = 0; int res = 0;
for (int i = 0; i < str.length(); i++) {
// Keeping track of counts of
// 0s and 1s.
if (str.charAt(i) == '0')
count_0++;
else
count_1++;
// If difference between current counts
// already exists, then substring between
// previous and current index has same
// no. of 0s and 1s. Update result if this
// substring is more than current result.
if (m[count_1 - count_0]!= 0) {
if ((i - m[count_1 - count_0]) > res) {
start = m[count_1 - count_0];
end = i;
res = end - start;
}
}
// If current difference
// is seen first time.
else
m[count_1 - count_0] = i;
}
if (count_0 == 0 || count_1 == 0)
return "-1";
// Return the substring
// between found indices
return str.substring(start , end + 2);
}
// Driver Code
public static void main (String[] args)
{
String str = "110101010";
System.out.println(stringLen(str));
}
}
// This code is contributed by Potta Lokesh
Python3
# Python for finding length
# of longest balanced substring
# Returns length of the longest substring
# with equal number of zeros and ones.
def stringLen (str) :
# Create a map to store differences
# between counts of 1s and 0s.
m = {}
# Initially difference is 0.
m[0] = -1
count_0 = 0
count_1 = 0
res = 0
for i in range(len(str)):
# Keeping track of counts of
# 0s and 1s.
if (str[i] == '0'):
count_0 += 1
else:
count_1 += 1
# If difference between current counts
# already exists, then substring between
# previous and current index has same
# no. of 0s and 1s. Update result if this
# substring is more than current result.
if ((count_1 - count_0) in m):
if ((i - m[count_1 - count_0]) > res):
start = m[(count_1 - count_0)]
end = i
res = end - start
# If current difference
# is seen first time.
else:
m[count_1 - count_0] = i
if (count_0 == 0 or count_1 == 0):
return "-1"
# Return the substring
# between found indices
return str[start + 1 : start + 1 + end + 1]
# Driver Code
str = "110101010"
print(stringLen(str))
# This code is contributed by Saurabh Jaiswal
C#
// C# code for the above approach
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
// Returns length of the longest substring
// with equal number of zeros and ones.
static string stringLen(string str)
{
// Create a map to store differences
// between counts of 1s and 0s.
int []m = new int[100000];
// Initially difference is 0.
m[0] = -1;
int count_0 = 0; int count_1 = 0;
int start = 0; int end = 0; int res = 0;
for (int i = 0; i < str.Length; i++) {
// Keeping track of counts of
// 0s and 1s.
if (str[i] == '0')
count_0++;
else
count_1++;
// If difference between current counts
// already exists, then substring between
// previous and current index has same
// no. of 0s and 1s. Update result if this
// substring is more than current result.
if (m[count_1 - count_0]!= 0) {
if ((i - m[count_1 - count_0]) > res) {
start = m[count_1 - count_0];
end = i;
res = end - start;
}
}
// If current difference
// is seen first time.
else
m[count_1 - count_0] = i;
}
if (count_0 == 0 || count_1 == 0)
return "-1";
// Return the substring
// between found indices
return str.Substring(start, end - start + 2);
}
// Driver Code
public static void Main ()
{
string str = "110101010";
Console.Write(stringLen(str));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
10101010
时间复杂度: O(N)
辅助空间: O(N)