Longest alternating sub-array starting from every index in a Binary Array

Given an array containing only 0s and 1s. For each index ‘i‘(0 index), find length of the longest alternating sub-array starting from ‘i‘ to ‘j‘ i.e., ai..j for i <= j < n. Alternating sub-array means that any two adjacent elements should be different.

Input: arr[] = {1, 0, 1, 0, 0, 1}
Output: 4 3 2 1 2 1 
Explanation
Length for index '0': {1 0 1 0} => 4
Length for index '1': {0 1 0}   => 3
Length for index '2': {1 0}     => 2
Length for index '3': {0}       => 1
Length for index '4': {0 1}     => 2
Length for index '5': {1}       => 1


Simple approach is to iterate for every index by using two ‘for loops’ for finding the length of each index. The outer loop picks a starting point ‘i’ and the inner loop considers all sub-arrays starting from ‘i’. Time complexity of this approach is O(n2) which is not sufficient for large value of ‘n’.

Better approach is to use Dynamic programming. First of all, let’s see how to check for alternating sub-array. To check whether two elements are alternating or not, we can simply take XOR(Ex-OR) of both of them and then compare with ‘0’ and ‘1’.

  • If there XOR is ‘0’, that means both numbers are not alternating(equal elements).
  • If there XOR is ‘1’, that means both are alternating(different elements)

Let len[i] denotes length of an alternating sub-array starting at position ‘i’. If arr[i] and arr[i+1] have different values, then len[i] will be one more than len[i+1]. Otherwise if they are same elements, len[i] will be just 1.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to calculate longest alternating
// sub-array for each index elements
#include <bits/stdc++.h>
using namespace std;
  
// Function to calculate alternating sub-
// array for each index of array elements
void alternateSubarray(bool arr[], int n)
{
    int len[n];
  
    // Initialize the base state of len[]
    len[n - 1] = 1;
  
    // Calculating value for each element
    for (int i = n - 2; i >= 0; --i) {
        // If both elements are different
        // then add 1 to next len[i+1]
        if (arr[i] ^ arr[i + 1] == 1)
            len[i] = len[i + 1] + 1;
  
        // else initialize to 1
        else
            len[i] = 1;
    }
  
    // Print lengths of binary subarrays.
    for (int i = 0; i < n; ++i)
        cout << len[i] << " ";
}
  
// Driver program
int main()
{
    bool arr[] = { 1, 0, 1, 0, 0, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    alternateSubarray(arr, n);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to calculate longest alternating
// sub-array for each index elements
  
class GFG {
      
// Function to calculate alternating sub-
// array for each index of array elements
static void alternateSubarray(boolean arr[], int n) 
{
    int len[] = new int[n];
  
    // Initialize the base state of len[]
    len[n - 1] = 1;
  
    // Calculating value for each element
    for (int i = n - 2; i >= 0; --i) {
          
    // If both elements are different
    // then add 1 to next len[i+1]
    if (arr[i] ^ arr[i + 1] == true)
        len[i] = len[i + 1] + 1;
  
    // else initialize to 1
    else
        len[i] = 1;
    }
  
    // Print lengths of binary subarrays.
    for (int i = 0; i < n; ++i)
    System.out.print(len[i] + " ");
}
  
// Driver code
public static void main(String[] args) 
{
    boolean arr[] = {true, false, true, false, false, true};
    int n = arr.length;
    alternateSubarray(arr, n);
}
}
  
// This code is contributed by Anant Agarwal.

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to calculate
# longest alternating
# sub-array for each index elements
  
# Function to calculate alternating sub-
# array for each index of array elements
def alternateSubarray(arr,n):
  
    len=[]
    for i in range(n+1):
        len.append(0)
          
    # Initialize the base state of len[]
    len[n - 1] = 1
   
    # Calculating value for each element
    for i in range(n - 2,-1,-1):
          
        # If both elements are different
        # then add 1 to next len[i+1]
        if (arr[i] ^ arr[i + 1] == True):
            len[i] = len[i + 1] + 1
   
        # else initialize to 1
        else:
            len[i] = 1
      
   
    # Print lengths of binary subarrays.
    for i in range(n):
        print(len[i] , " ",end="")
   
# Driver code
  
arr = [ True,False, True, False, False, True ]
n = len(arr)
  
alternateSubarray(arr, n)
  
# This code is contributed
# by Anant Agarwal.

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to calculate longest 
// alternating sub-array for each 
// index elements
using System;
  
class GFG {
      
    // Function to calculate alternating sub-
    // array for each index of array elements
    static void alternateSubarray(bool []arr,
                                        int n) 
    {
          
        int []len = new int[n];
      
        // Initialize the base state of len[]
        len[n - 1] = 1;
      
        // Calculating value for each element
        for (int i = n - 2; i >= 0; --i)
        {
              
            // If both elements are different
            // then add 1 to next len[i+1]
            if (arr[i] ^ arr[i + 1] == true)
                len[i] = len[i + 1] + 1;
          
            // else initialize to 1
            else
                len[i] = 1;
        }
      
        // Print lengths of binary subarrays.
        for (int i = 0; i < n; ++i)
            Console.Write(len[i] + " ");
    }
      
    // Driver code
    public static void Main() 
    {
        bool []arr = {true, false, true
                         false, false, true};
        int n = arr.Length;
          
        alternateSubarray(arr, n);
    }
}
  
// This code is contributed by vt_m.

chevron_right



Output :

4 3 2 1 2 1

Time complexity: O(n)
Auxiliary space: O(n)

Another Efficient approach is, instead of storing all the sub-array elements in len[] array, we can directly print it until mismatch(equal adjacent elements) is found. When a mismatch is found, we print count from current value to 0.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to calculate longest alternating
// sub-array for each index elements
#include <bits/stdc++.h>
using namespace std;
  
// Function to calculate alternating sub-array
// for each index of array elements
void alternateSubarray(bool arr[], int n)
{
    // Initialize count variable for storing
    // length of sub-array
    int count = 1;
  
    // Initialize 'prev' variable which
    // indicates the previous element
    // while traversing for index 'i'
    int prev = arr[0];
    for (int i = 1; i < n; ++i) {
  
        // If both elements are same
        // print elements because alternate
        // element is not found for current
        // index
        if ((arr[i] ^ prev) == 0)
        {
            // print count and decrement it.
            while (count)
                cout << count-- << " ";
        }
  
        // Increment count for next element
        ++count;
  
        // Re-initialize previous variable
        prev = arr[i];
    }
  
    // If elements are still available after
    // traversing whole array, print it
    while (count)
        cout << count-- << " ";
}
  
// Driver program
int main()
{
    bool arr[] = { 1, 0, 1, 0, 0, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    alternateSubarray(arr, n);
    return 0;
}

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to calculate longest alternating
// sub-array for each index elements
  
// Function to calculate alternating sub-array
// for each index of array elements
function alternateSubarray($arr, $n)
{
      
    // Initialize count variable for storing
    // length of sub-array
    $count = 1;
  
    // Initialize 'prev' variable which
    // indicates the previous element
    // while traversing for index 'i'
    $prev = $arr[0];
    for ($i = 1; $i < $n; ++$i)
    {
  
        // If both elements are same
        // print elements because alternate
        // element is not found for current
        // index
        if (($arr[$i] ^ $prev) == 0)
        {
            // print count and decrement it.
            while ($count)
                echo $count-- , " ";
        }
  
        // Increment count for next element
        ++$count;
  
        // Re-initialize previous variable
        $prev = $arr[$i];
    }
  
    // If elements are still available after
    // traversing whole array, print it
    while ($count)
        echo $count-- , " ";
}
  
    // Driver Code
    $arr = array(1, 0, 1, 0, 0, 1);
    $n = sizeof($arr) ;
    alternateSubarray($arr, $n);
      
// This code is contributed by jit_t.
?>

chevron_right



Output :

4 3 2 1 2 1

Time complexity: O(n)
Auxiliary space: O(1)

This article is contributed by Shubham Bansal. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.



My Personal Notes arrow_drop_up

Improved By : vt_m, jit_t