Open In App

Construct lexicographically smallest Binary array of size N with A 0s and X inversion count

Last Updated : 09 Nov, 2021
Comments
Improve
Suggest changes
Like Article
Like
Report

Given three numbers N, A, and X, the task is to construct the lexicographically smallest binary array of size N, containing A 0s and having an inversion count of X.

Examples:

Input: N=5, A=2, X=1
Output: 0 1 0 1 1
Explanation: 
The number of inversions in this array is 1(2nd and 3rd index).

Input: N=5, A=2, X=3
Output: 0 1 1 1 0

 

Approach: The given problem can be solved using two pointer technique based on the following observations: 

  1. The array with A 0s having 0 inversion is the array with all 0s to the beginning and then the all the 1s.
  2. If an element 0 at index i and an element 1 at index j is swapped, then inversion count increases by count of 1s in the range [i, j].
  3. The maximum possible inversion count is A*(N-A).

Follow the steps below to solve the problem:

  • If X is greater than A*(N-A), print -1 and then return.
  • Initialize an array say arr[] of size N and fill the first A Indices with 0s and the remaining with 1s.
  • Initialize two variables curr as A-1 and prev as N-1 to iterate over the array.
  • Iterate until X is greater than 0 and curr, is not less than 0, and perform the following steps:
    • If X is greater than or equal prev-cur, then do the following:
      • Swap the two elements at arr[prev], and arr[curr].
      • Subtract prev-cur from X.
      • Decrement prev and curr by 1.
    • Otherwise, do the following:
      • Swap the two elements arr[curr] and arr[cur+1].
      • Increment curr by 1 and decrement X by 1.
  • Print the array arr.

Below is the implementation of the above approach:

C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;

// Function to construct lexicographically
// smallest binary string of length N, having
// A 0s and X inversions
void binaryArrayInversions(int N, int A, int X)
{
    // If X inversions are not possible
    if (A * (N - A) < X) {
        cout << "-1";
        return;
    }
    // Initialize array and fill with 0
    int Arr[N] = { 0 };

    // Fill last N-A indices with 1
    fill(Arr + A, Arr + N, 1);

    // Stores the index of current 0
    int cur = A - 1;

    // Stores the index of current 1
    int prev = N - 1;

    // Iterate until X is greater than
    // 0 and cur is greater than equal
    // to 0
    while (X && cur >= 0) {
        // If X is greater than or
        // equal to the prev-cur

        if (X >= prev - cur) {
            // Swap current 0 and current 1
            swap(Arr[prev], Arr[cur]);

            // Update X
            X -= prev - cur;

            // Decrement prev and cur by 1
            prev--;
            cur--;
        }
        // Otherwise
        else {
            // Swap current 0 with the next index
            swap(Arr[cur], Arr[cur + 1]);

            // Increment cur by 1
            cur++;
            // Decrement X by 1
            X--;
        }
    }
    // Print the array
    for (auto u : Arr)
        cout << u << " ";
}
// Driver code
int main()
{
    // Input
    int N = 5;
    int A = 2;
    int X = 1;

    // Function call
    binaryArrayInversions(N, A, X);
    return 0;
}
Java Python3 C# JavaScript

Output
0 1 0 1 1 

Time complexity: O(N)
Auxiliary Space: O(1)


 


Next Article

Similar Reads