📜  1s 多于 0s 的最长子串

📅  最后修改于: 2021-10-27 07:27:09             🧑  作者: Mango

给定一个二进制字符串,找到包含 1 多于 0 的最长子字符串。
例子:

Input : 1010
Output : 3
Substring 101 has 1 occurring more number of times than 0.

Input : 101100
Output : 5
Substring 10110 has 1 occurring more number of times than 0.
推荐:请先在 IDE 上尝试您的方法,然后再查看解决方案。

一个简单的解决方案是逐一考虑所有子字符串并检查该子字符串的计数是否大于 0。如果计数大于将其长度与迄今为止找到的最大长度子字符串进行比较。该解决方案的时间复杂度为 O(n^2)。
一个有效的解决方案是使用散列。这个想法是找到到目前为止遍历的字符串的总和。如果当前字符为“1”,则将结果加 1,否则减 1。现在问题简化为找到总和大于零的最大子数组。为了找到总和大于零的最大子数组,我们检查总和的值。如果总和大于零,则总和大于零的最大子数组是 arr[0..i]。如果总和小于零,则找到子数组 arr[j+1..i] 的大小,其中 j 是索引,直到子数组 arr[0..j] 的总和为 sum -1 且 j < i 和将该大小与迄今为止发现的最大子数组大小进行比较。要找到索引 j,请将 arr[0..j] 的 sum 值存储在哈希表中,所有 0 <= j <= i。可能存在重复给定 sum 值的可能性。在这种情况下,仅存储获得该总和的第一个索引,因为需要获得最大子数组的长度并且从第一个索引出现中获得。
下面是上述方法的实现:

C++
// CPP program to find largest substring
// having count of 1s more than count
// count of 0s.
#include 
using namespace std;
 
// Function to find longest substring
// having count of 1s more than count
// of 0s.
int findLongestSub(string bin)
{
    int n = bin.length(), i;
 
    // To store sum.
    int sum = 0;
 
    // To store first occurrence of each
    // sum value.
    unordered_map prevSum;
 
    // To store maximum length.
    int maxlen = 0;
 
    // To store current substring length.
    int currlen;
 
    for (i = 0; i < n; i++) {
 
        // Add 1 if current character is 1
        // else subtract 1.
        if (bin[i] == '1')
            sum++;
        else
            sum--;
 
        // If sum is positive, then maximum
        // length substring is bin[0..i]
        if (sum > 0) {
            maxlen = i + 1;
        }
 
        // If sum is negative, then maximum
        // length substring is bin[j+1..i], where
        // sum of substring bin[0..j] is sum-1.
        else if (sum <= 0) {
            if (prevSum.find(sum - 1) != prevSum.end()) {
                currlen = i - prevSum[sum - 1];
                maxlen = max(maxlen, currlen);
            }
        }
 
        // Make entry for this sum value in hash
        // table if this value is not present.
        if (prevSum.find(sum) == prevSum.end())
            prevSum[sum] = i;
    }
 
    return maxlen;
}
 
// Driver code
int main()
{
    string bin = "1010";
    cout << findLongestSub(bin);
    return 0;
}


Java
// Java program to find largest substring
// having count of 1s more than count
// count of 0s.
import java.util.HashMap;
 
class GFG
{
 
    // Function to find longest substring
    // having count of 1s more than count
    // of 0s.
    static int findLongestSub(String bin)
    {
        int n = bin.length(), i;
 
        // To store sum.
        int sum = 0;
 
        // To store first occurrence of each
        // sum value.
        HashMap prevSum = new HashMap<>();
 
        // To store maximum length.
        int maxlen = 0;
 
        // To store current substring length.
        int currlen;
        for (i = 0; i < n; i++)
        {
 
            // Add 1 if current character is 1
            // else subtract 1.
            if (bin.charAt(i) == '1')
                sum++;
            else
                sum--;
 
            // If sum is positive, then maximum
            // length substring is bin[0..i]
            if (sum > 0)
            {
                maxlen = i + 1;
            }
 
            // If sum is negative, then maximum
            // length substring is bin[j+1..i], where
            // sum of substring bin[0..j] is sum-1.
            else if (sum <= 0)
             
            {
                if (prevSum.containsKey(sum - 1))
                {
                    currlen = i - (prevSum.get(sum - 1) == null ? 1 :
                                   prevSum.get(sum - 1));
                    maxlen = Math.max(maxlen, currlen);
                }
            }
 
            // Make entry for this sum value in hash
            // table if this value is not present.
            if (!prevSum.containsKey(sum))
                prevSum.put(sum, i);
        }
        return maxlen;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        String bin = "1010";
        System.out.println(findLongestSub(bin));
    }
}
 
// This code is contributed by
// sanjeev2552


Python3
# Python 3 program to find largest substring
# having count of 1s more than count
# count of 0s.
 
# Function to find longest substring
# having count of 1s more than count
# of 0s.
def findLongestSub(bin1):
    n = len(bin1)
 
    # To store sum.
    sum = 0
 
    # To store first occurrence of each
    # sum value.
    prevSum = {i:0 for i in range(n)}
 
    # To store maximum length.
    maxlen = 0
 
    # To store current substring length.
    for i in range(n):
         
        # Add 1 if current character is 1
        # else subtract 1.
        if (bin1[i] == '1'):
            sum += 1
        else:
            sum -= 1
 
        # If sum is positive, then maximum
        # length substring is bin1[0..i]
        if (sum > 0):
            maxlen = i + 1
 
        # If sum is negative, then maximum
        # length substring is bin1[j+1..i], where
        # sum of substring bin1[0..j] is sum-1.
        elif (sum <= 0):
            if ((sum - 1) in prevSum):
                currlen = i - prevSum[sum - 1]
                maxlen = max(maxlen, currlen)
         
        # Make entry for this sum value in hash
        # table if this value is not present.
        if ((sum) not in prevSum):
            prevSum[sum] = i
 
    return maxlen
 
# Driver code
if __name__ == '__main__':
    bin1 = "1010"
    print(findLongestSub(bin1))
 
# This code is contributed by
# Surendra_Gangwar


C#
// C# program to find largest substring
// having count of 1s more than count
// count of 0s.
using System;
using System.Collections.Generic;
class GFG
{
 
    // Function to find longest substring
    // having count of 1s more than count
    // of 0s.
    static int findLongestSub(String bin)
    {
        int n = bin.Length, i;
 
        // To store sum.
        int sum = 0;
 
        // To store first occurrence of each
        // sum value.
        Dictionary prevSum = new Dictionary();
 
        // To store maximum length.
        int maxlen = 0;
 
        // To store current substring length.
        int currlen;
        for (i = 0; i < n; i++)
        {
 
            // Add 1 if current character is 1
            // else subtract 1.
            if (bin[i] == '1')
                sum++;
            else
                sum--;
 
            // If sum is positive, then maximum
            // length substring is bin[0..i]
            if (sum > 0)
            {
                maxlen = i + 1;
            }
 
            // If sum is negative, then maximum
            // length substring is bin[j+1..i], where
            // sum of substring bin[0..j] is sum-1.
            else if (sum <= 0)
             
            {
                if (prevSum.ContainsKey(sum - 1))
                {
                    currlen = i - (prevSum[sum - 1] == 0 ? 1 :
                                   prevSum[sum - 1]);
                    maxlen = Math.Max(maxlen, currlen);
                }
            }
 
            // Make entry for this sum value in hash
            // table if this value is not present.
            if (!prevSum.ContainsKey(sum))
                prevSum.Add(sum, i);
        }
        return maxlen;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        String bin = "1010";
        Console.WriteLine(findLongestSub(bin));
    }
}
 
// This code is contributed by 29AjayKumar


Javascript


输出:

3

时间复杂度: O(n)
辅助空间: O(n)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程