Maximum length of segments of 0’s and 1’s
Last Updated :
29 Aug, 2023
Given a string comprising of ones and zeros. The task is to find the maximum length of the segments of string such that a number of 1 in each segment is greater than 0.
Note: Each segment taken should be distinct. Index starts from 0.
Examples:
Input: str = “100110001010001”
Output: 9
First segment from index 0 to 4 (10011), total length = 5
Second segment from index 8 to 10 (101), total length = 3
Third segment from index 14 till 14 (1), total length = 1,
Hence answer is 5 + 3 + 1 = 9
Input: str = “0010111101100000”
Output: 13
The maximum length can be formed by taking segment
from index 0 till index 12 (0010111101100),
i.e. of total length = 13
Approach:
- If start == n, limiting condition arises, return 0.
- Run a loop from start till n, computing for each subarray till n.
- If character is 1 then increment the count of 1 else increment the count of 0.
- If count of 1 is greater than 0, recursively call the function for index (k+1) i.e. next index and add the remaining length i.e. k-start+1.
- Else only recursively call the function for next index k+1.
- Return dp[start].
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int find( int start, string adj, int n, int dp[])
{
if (start == n)
return 0;
if (dp[start] != -1)
return dp[start];
dp[start] = 0;
int one = 0, zero = 0, k;
for (k = start; k < n; k++) {
if (adj[k] == '1' )
one++;
else
zero++;
if (one > zero)
dp[start] = max(dp[start], find(k + 1, adj, n, dp)
+ k - start + 1);
else
dp[start] = max(dp[start], find(k + 1, adj, n, dp));
}
return dp[start];
}
int main()
{
string adj = "100110001010001" ;
int n = adj.size();
int dp[n + 1];
memset (dp, -1, sizeof (dp));
cout << find(0, adj, n, dp) << endl;
return 0;
}
|
Java
import java.util.*;
import java.lang.Math;
class GFG
{
public static int find( int start, String adj,
int n, int dp[])
{
if (start == n)
return 0 ;
if (dp[start] != - 1 )
return dp[start];
dp[start] = 0 ;
int one = 0 , zero = 0 , k;
for (k = start; k < n; k++)
{
if (adj.charAt(k) == '1' )
one++;
else
zero++;
if (one > zero)
dp[start] = Math.max(dp[start],
find(k + 1 , adj, n, dp) +
k - start + 1 );
else
dp[start] = Math.max(dp[start],
find(k + 1 , adj, n, dp));
}
return dp[start];
}
public static void main (String[] args)
{
String adj = "100110001010001" ;
int n = adj.length();
int dp[] = new int [n + 1 ];
Arrays.fill(dp, - 1 );
System.out.println(find( 0 , adj, n, dp));
}
}
|
Python3
def find(start, adj, n, dp):
if (start = = n):
return 0
if (dp[start] ! = - 1 ):
return dp[start]
dp[start] = 0
one = 0
zero = 0
for k in range (start, n, 1 ):
if (adj[k] = = '1' ):
one + = 1
else :
zero + = 1
if (one > zero):
dp[start] = max (dp[start],
find(k + 1 , adj, n, dp) +
k - start + 1 )
else :
dp[start] = max (dp[start],
find(k + 1 , adj, n, dp))
return dp[start]
if __name__ = = '__main__' :
adj = "100110001010001"
n = len (adj)
dp = [ - 1 for i in range (n + 1 )]
print (find( 0 , adj, n, dp))
|
C#
using System;
class GFG
{
public static int find( int start, string adj, int n, int [] dp)
{
if (start == n)
return 0;
if (dp[start] != -1)
return dp[start];
dp[start] = 0;
int one = 0, zero = 0, k;
for (k = start; k < n; k++) {
if (adj[k] == '1' )
one++;
else
zero++;
if (one > zero)
dp[start] = Math.Max(dp[start], find(k + 1, adj, n, dp)
+ k - start + 1);
else
dp[start] = Math.Max(dp[start], find(k + 1, adj, n, dp));
}
return dp[start];
}
static void Main()
{
string adj = "100110001010001" ;
int n = adj.Length;
int [] dp = new int [n + 1];
for ( int i = 0; i <= n; i++)
dp[i] = -1;
Console.Write(find(0, adj, n, dp) + "\n" );
}
}
|
Javascript
<script>
function find(start, adj , n , dp) {
if (start == n)
return 0;
if (dp[start] != -1)
return dp[start];
dp[start] = 0;
var one = 0, zero = 0, k;
for (k = start; k < n; k++) {
if (adj[k] == '1' )
one++;
else
zero++;
if (one > zero)
dp[start] = Math.max(dp[start], find(k + 1, adj, n, dp) + k - start + 1);
else
dp[start] = Math.max(dp[start], find(k + 1, adj, n, dp));
}
return dp[start];
}
var adj = "100110001010001" ;
var n = adj.length;
var dp = Array(n + 1).fill(-1);
document.write(find(0, adj, n, dp));
</script>
|
PHP
<?php
function find( $start , $adj , $n , $dp )
{
if ( $start == $n )
return 0;
if ( $dp [ $start ] != -1)
return $dp [ $start ];
$dp [ $start ] = 0;
$one = 0;
$zero = 0;
for ( $k = $start ; $k < $n ; $k ++)
{
if ( $adj [ $k ] == '1' )
$one ++;
else
$zero ++;
if ( $one > $zero )
$dp [ $start ] = max( $dp [ $start ],
find( $k + 1, $adj , $n , $dp ) +
$k - $start + 1);
else
$dp [ $start ] = max( $dp [ $start ],
find( $k + 1, $adj , $n , $dp ));
}
return $dp [ $start ];
}
$adj = "100110001010001" ;
$n = strlen ( $adj );
$dp = array_fill (0, $n + 1, -1);
echo find(0, $adj , $n , $dp );
?>
|
Another approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Implementation :
C++
#include <bits/stdc++.h>
using namespace std;
int find(string adj, int n)
{
int dp[n + 1];
for ( int i = 0; i <= n; i++) {
dp[i] = 0;
}
for ( int i = 0; i < n; i++) {
int one = 0, zero = 0;
for ( int j = i; j < n; j++) {
if (adj[j] == '1' )
one++;
else
zero++;
if (one > zero)
dp[j + 1]
= max(dp[j + 1], dp[i] + j - i + 1);
else
dp[j + 1] = max(dp[j + 1], dp[i]);
}
}
return dp[n];
}
int main()
{
string adj = "100110001010001" ;
int n = adj.size();
cout << find(adj, n) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
static int find(String adj, int n)
{
int [] dp = new int [n + 1 ];
for ( int i = 0 ; i <= n; i++) {
dp[i] = 0 ;
}
for ( int i = 0 ; i < n; i++) {
int one = 0 , zero = 0 ;
for ( int j = i; j < n; j++) {
if (adj.charAt(j) == '1' )
one++;
else
zero++;
if (one > zero)
dp[j + 1 ] = Math.max(dp[j + 1 ],
dp[i] + j - i + 1 );
else
dp[j + 1 ] = Math.max(dp[j + 1 ], dp[i]);
}
}
return dp[n];
}
public static void main(String[] args)
{
String adj = "100110001010001" ;
int n = adj.length();
System.out.println(find(adj, n));
}
}
|
Python3
def find(adj, n):
dp = [ 0 ] * (n + 1 )
for i in range (n):
one = 0
zero = 0
for j in range (i, n):
if adj[j] = = '1' :
one + = 1
else :
zero + = 1
if one > zero:
dp[j + 1 ] = max (dp[j + 1 ], dp[i] + j - i + 1 )
else :
dp[j + 1 ] = max (dp[j + 1 ], dp[i])
return dp[n]
adj = "100110001010001"
n = len (adj)
print (find(adj, n))
|
C#
using System;
public class GFG {
static int Find( string adj, int n) {
int [] dp = new int [n + 1];
for ( int i = 0; i <= n; i++) {
dp[i] = 0;
}
for ( int i = 0; i < n; i++) {
int one = 0, zero = 0;
for ( int j = i; j < n; j++) {
if (adj[j] == '1' )
one++;
else
zero++;
if (one > zero)
dp[j + 1] = Math.Max(dp[j + 1], dp[i] + j - i + 1);
else
dp[j + 1] = Math.Max(dp[j + 1], dp[i]);
}
}
return dp[n];
}
static void Main( string [] args) {
string adj = "100110001010001" ;
int n = adj.Length;
Console.WriteLine(Find(adj, n));
}
}
|
Javascript
function find(adj, n) {
let dp = new Array(n + 1).fill(0);
for (let i = 0; i < n; i++) {
let one = 0, zero = 0;
for (let j = i; j < n; j++) {
if (adj[j] === '1' )
one++;
else
zero++;
if (one > zero)
dp[j + 1] = Math.max(dp[j + 1], dp[i] + j - i + 1);
else
dp[j + 1] = Math.max(dp[j + 1], dp[i]);
}
}
return dp[n];
}
let adj = "100110001010001" ;
let n = adj.length;
console.log(find(adj, n));
|
Time Complexity: O(N^2)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...