Open In App

Length of longest consecutive sequence that can be formed from Array by converting 0s

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr of N integers, the task is to calculate the length of longest sequence of consecutive integers that can be formed from the array. It is also given that 0’s in the array can be converted to any value.

Example:

Input: N = 7, A = {0, 6, 5, 10, 3, 0, 11}
Output: 5
Explanation: The maximum consecutive sequence formed can be {3, 4, 5, 6, 7}. As 4, 7 are not present in the array, we can change 2 zeroes to 4 and 7.

Input: N = 6, A = {0, 0, 1, 2, 6, 0}
Output: 6
Explanation: The maximum consecutive sequence formed can be {1, 2, 3, 4, 5, 6}

 

Approach: Given problem can be solved with the help of binary search and prefix sum array:

  • Calculate total zeroes in the array and store them in a variable count which indicates the total possible changes that can be made
  • Repeating and zero values in the given array are removed so that array contains only unique non-zero values
  • Create an auxiliary array and initialize those indices value to 1, whose values are present in the given array
  • Auxiliary array is turned into prefix sum array
  • Iterate the prefix array and at every iteration perform binary search with lower limit as current index and upper limit as last index of the array
  • Let current index be l and the rightmost possible index as r. For each mid = (l + r) / 2, Check if this range[l, mid] is achievable with total allowed changes
  • Update l = mid +1 if the above statement is true otherwise r = mid – 1
  • Calculate maximum length for all starting values

Below is the implementation of the above approach: 

C++




// C++ implementation for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate maximum
// possible consecutive numbers
// with changes allowed
int maximumConsecutiveNumbers(int arr[], int N)
{
    // Store all non-zero elements
    // in a new vector and
    // calculate total zero elements
    vector<int> v;
 
    // Variable to store the
    // count of zero elements
    int count = 0;
 
    for (int i = 0; i < N; i++) {
        if (arr[i] == 0) {
            count++;
        }
        else {
            v.push_back(arr[i]);
        }
    }
 
    // Sort the array
    sort(v.begin(), v.end());
 
    // Remove all the duplicates
    // from the array
    (v).erase(unique(v.begin(),
                     v.end()),
              (v).end());
 
    // Variable to store the maximum
    // value of the sequence
    int MAXN = 1100000;
 
    // Make the prefix array
    vector<int> pref(MAXN + 1, 0);
 
    for (int i = 0; i < v.size(); i++) {
        pref[v[i]]++;
    }
 
    for (int i = 1; i <= MAXN; i++) {
        pref[i] += pref[i - 1];
    }
 
    int mx = 0;
 
    // Iterate for each element and
    // use binary search
    for (int i = 1; i <= MAXN; i++) {
 
        int l = i, r = MAXN;
        int local_max = 0;
        while (l <= r) {
            int mid = (l + r) / 2;
 
            // Conversions equal to number
            // of zeros, can be made upto mid
            if (pref[mid] - pref[i - 1]
                    + count
                >= (mid - i + 1)) {
 
                l = mid + 1;
                local_max = max(local_max,
                                mid - i + 1);
            }
 
            else {
                r = mid - 1;
            }
        }
        mx = max(mx, local_max);
    }
    return mx;
}
 
// Driver Code
int main()
{
    int N = 7;
    int arr[] = { 0, 6, 5, 10, 3, 0, 11 };
    cout << maximumConsecutiveNumbers(arr, N);
}


Java




import java.util.*;
 
public class Main {
 
    public static int maximumConsecutiveNumbers(int[] arr)
    {
        // Store all non-zero elements
        // in a new List and
        // calculate total zero elements
        List<Integer> v = new ArrayList<>();
 
        // Variable to store the
        // count of zero elements
        int count = 0;
 
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == 0) {
                count++;
            }
            else {
                v.add(arr[i]);
            }
        }
 
        // Sort the array
        Collections.sort(v);
 
        // Remove all the duplicates
        // from the array
        for (int i = 1; i < v.size(); i++) {
            if (v.get(i) == v.get(i - 1)) {
                v.remove(i);
                i--;
            }
        }
 
        // Variable to store the maximum
        // value of the sequence
        int MAXN = 1100000;
 
        // Make the prefix array
        int[] pref = new int[MAXN + 1];
        Arrays.fill(pref, 0);
 
        for (int i = 0; i < v.size(); i++) {
            pref[v.get(i)]++;
        }
 
        for (int i = 1; i <= MAXN; i++) {
            pref[i] += pref[i - 1];
        }
 
        int mx = 0;
 
        // Iterate for each element and
        // use
        for (int i = 1; i <= MAXN; i++) {
            int l = i, r = MAXN;
            int localMax = 0;
            while (l <= r) {
                int mid = (l + r) / 2;
                // Conversions equal to number
                // of zeros, can be made upto mid
                if (pref[mid] - pref[i - 1] + count
                    >= (mid - i + 1)) {
                    l = mid + 1;
                    localMax
                        = Math.max(localMax, mid - i + 1);
                }
                else {
                    r = mid - 1;
                }
            }
            mx = Math.max(mx, localMax);
        }
        return mx;
    }
 
    public static void main(String[] args)
    {
        int N = 7;
        int arr[] = { 0, 6, 5, 10, 3, 0, 11 };
        System.out.println(maximumConsecutiveNumbers(arr));
    }
}


Python3




# Python 3 implementation for the above approach
 
# Function to calculate maximum
# possible consecutive numbers
# with changes allowed
def maximumConsecutiveNumbers(arr, N):
   
    # Store all non-zero elements
    # in a new vector and
    # calculate total zero elements
    v = []
 
    # Variable to store the
    # count of zero elements
    count = 0
 
    for i in range(N):
        if(arr[i] == 0):
            count += 1
        else:
            v.append(arr[i])
 
    # Sort the array
    v.sort()
 
    # Remove all the duplicates
    # from the array
    v = set(v)
    v = list(v)
    # Variable to store the maximum
    # value of the sequence
    MAXN = 110000
 
    # Make the prefix array
    pref = [0 for i in range(MAXN+1)]
 
    for i in range(len(v)):
        pref[v[i]] += 1
 
    for i in range(1,MAXN+1,1):
        pref[i] += pref[i - 1]
 
    mx = 0
 
    # Iterate for each element and
    # use binary search
    for i in range(1,MAXN+1,1):
        l = i
        r = MAXN
        local_max = 0
        while (l <= r):
            mid = (l + r) // 2
 
            # Conversions equal to number
            # of zeros, can be made upto mid
            if (pref[mid] - pref[i - 1] + count >= (mid - i + 1)):
                l = mid + 1
                local_max = max(local_max,mid - i + 1)
 
            else:
                r = mid - 1
        mx = max(mx, local_max)
    return mx
 
# Driver Code
if __name__ == '__main__':
    N = 7
    arr = [0, 6, 5, 10, 3, 0, 11]
    print(maximumConsecutiveNumbers(arr, N))
     
    # This code is contributed by ipg2016107.


C#




// C# implementation for the above approach
using System;
using System.Collections.Generic;
using System.Linq;
 
class GFG
{
   
    // Function to calculate maximum
    // possible consecutive numbers
    // with changes allowed
    static int maximumConsecutiveNumbers(int[] arr, int N)
    {
        // Store all non-zero elements
        // in a new vector and
        // calculate total zero elements
        List<int> v = new List<int>();
 
        // Variable to store the
        // count of zero elements
        int count = 0;
 
        for (int i = 0; i < N; i++) {
            if (arr[i] == 0) {
                count++;
            }
            else {
                v.Add(arr[i]);
            }
        }
 
        // Sort the array
        v.Sort();
 
        // Remove all the duplicates
        // from the array
        List<int> distinct = v.Distinct().ToList();
 
        // Variable to store the maximum
        // value of the sequence
        int MAXN = 1100000;
 
        // Make the prefix array
        List<int> pref = new List<int>(new int[MAXN + 1]);
 
        for (int i = 0; i < distinct.Count; i++) {
            pref[distinct[i]]++;
        }
 
        for (int i = 1; i <= MAXN; i++) {
            pref[i] += pref[i - 1];
        }
 
        int mx = 0;
 
        // Iterate for each element and
        // use binary search
        for (int i = 1; i <= MAXN; i++) {
 
            int l = i, r = MAXN;
            int local_max = 0;
            while (l <= r) {
                int mid = (l + r) / 2;
 
                // Conversions equal to number
                // of zeros, can be made upto mid
                if (pref[mid] - pref[i - 1] + count
                    >= (mid - i + 1)) {
 
                    l = mid + 1;
                    local_max
                        = Math.Max(local_max, mid - i + 1);
                }
 
                else {
                    r = mid - 1;
                }
            }
            mx = Math.Max(mx, local_max);
        }
        return mx;
    }
 
    // Driver Code
    public static void Main()
    {
        int N = 7;
        int[] arr = { 0, 6, 5, 10, 3, 0, 11 };
        Console.Write(maximumConsecutiveNumbers(arr, N));
    }
}
 
// This code is contributed by ukasp.


Javascript




<script>
    // Javascript implementation for the above approach
 
    // Function to calculate maximum
    // possible consecutive numbers
    // with changes allowed
    const maximumConsecutiveNumbers = (arr, N) => {
        
       // Store all non-zero elements
        // in a new vector and
        // calculate total zero elements
        let v = [];
 
        // Variable to store the
        // count of zero elements
        let count = 0;
 
        for (let i = 0; i < N; i++) {
            if (arr[i] == 0) {
                count++;
            }
            else {
                v.push(arr[i]);
            }
        }
 
        // Sort the array
 
        // Remove all the duplicates
        // from the array
       
        v = [...new Set(v)];
         
        // Variable to store the maximum
        // value of the sequence
        let MAXN = 1100000;
 
        // Make the prefix array
        let pref = new Array(MAXN + 1).fill(0);
 
        for (let i = 0; i < v.length; i++) {
            pref[v[i]]++;
        }
 
        for (let i = 1; i <= MAXN; i++) {
            pref[i] += pref[i - 1];
        }
 
        let mx = 0;
 
        // Iterate for each element and
        // use binary search
        for (let i = 1; i <= MAXN; i++) {
 
            let l = i, r = MAXN;
            let local_max = 0;
            while (l <= r) {
                let mid = parseInt((l + r) / 2);
 
                // Conversions equal to number
                // of zeros, can be made upto mid
                if (pref[mid] - pref[i - 1]
                    + count
                    >= (mid - i + 1)) {
 
                    l = mid + 1;
                    local_max = Math.max(local_max,
                        mid - i + 1);
                }
 
                else {
                    r = mid - 1;
                }
            }
            mx = Math.max(mx, local_max);
        }
        return mx;
    }
 
    // Driver Code
    let N = 7;
    let arr = [0, 6, 5, 10, 3, 0, 11];
     
    document.write(maximumConsecutiveNumbers(arr, N))
 
    // This code is contributed by rakeshsahni
 
</script>


Output

5

Time Complexity: O(N*log(K)), where K is maximum value in the array 
Auxiliary Space: O(N)



Last Updated : 25 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads