Open In App

Construction of multiple AP Arrays

Last Updated : 19 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A[] of N integers, the task is to check if it is possible to construct several arrays (at least one) using all the elements of the array A[] such that in each array, the value of each element is equal to the number of elements to its left.

Examples:

Input: N = 9, A[] = {0, 0, 0, 0, 1, 1, 1, 2, 2}
Output: YES
Explanation: The array A[] can be divided into 4 arrays as follows –

  • {0,1,2} -> 1st element (0) has 0 elements to its left, 2nd element (1) has 1 element to its left and 3rd element (2) has 2 elements to its left
  • {0,1} -> 1st element (0) has 0 elements to its left and 2nd element (1) has 1 element to its left
  • {0,1,2} -> 1st element (0) has 0 elements to its left, 2nd element (1) has 1 element to its left and 3rd element (2) has 2 elements to its left
  • {0} -> 1st element (0) has 0 elements to its left

Input: N = 3, A[] = {0, 0, 2}
Output: NO

Approach: To solve the problem follow the below observations:

Observation:

  • The problem can be rephrased as ” Is it possible to divide input array in Arithmetic Progressions each having the first digit 0 and a common difference equal to 1 “?
    • For each A.P., if an integer X is a part of it, then X-1 must also be there. So, in the whole sequence if X occurs “count” times, then X-1 must also occur at least count times.

Following is the code based on the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to Check if it is possible
// to construct several number
// of arrays from the given array
// satisfying the given condition
bool isPossible(int N, int A[])
{
 
    // Initialize flag variable to
    // store the answer
    bool flag = true;
 
    // Initializing an unordered_map to
    // store frequency of each element
    unordered_map<int, int> mp;
 
    // Iterating through the array
    for (int i = 0; i < N; i++) {
        // If the current element is less
        // than N, increment
        // its frequency in map
        if (A[i] < N) {
            mp[A[i]]++;
        }
 
        // Else, make the value of flag = false
        // (as there can never be more than
        // N elements before any
        // element in the array)
        else {
            flag = false;
        }
    }
 
    // Iterate from 1 to N and check the
    // required condition
    for (int i = 1; i <= N; i++) {
        if (mp[i] > mp[i - 1]) {
            flag = false;
            break;
        }
    }
 
    return flag;
}
 
// Driver code
int main()
{
    int N = 9;
    int A[] = { 0, 0, 0, 0, 1, 1, 1, 2, 2 };
 
    // Function Call
    int answer = isPossible(N, A);
    if (answer == 1) {
        cout << "YES";
    }
    else {
        cout << "NO";
    }
}


Java




import java.util.HashMap;
 
public class GFG {
 
    // Function to Check if it is possible
    // to construct several number
    // of arrays from the given array
    static boolean isPossible(int N, int[] A) {
 
        // Initialize flag variable to
        // store the answer
        boolean flag = true;
 
        // Initializing a HashMap to
        // store frequency of each element
        HashMap<Integer, Integer> map = new HashMap<>();
 
        // Iterating through the array
        for (int i = 0; i < N; i++) {
            // If the current element is less
            // than N, increment
            // its frequency in the map
            if (A[i] < N) {
                map.put(A[i], map.getOrDefault(A[i], 0) + 1);
            }
 
            // Else, make the value of flag = false
            // (as there can never be more than
            // N elements before any
            // element in the array)
            else {
                flag = false;
            }
        }
 
        // Iterate from 1 to N and check the
        // required condition
        for (int i = 1; i <= N; i++) {
            if (map.getOrDefault(i, 0) > map.getOrDefault(i - 1, 0)) {
                flag = false;
                break;
            }
        }
 
        return flag;
    }
 
    // Driver code
    public static void main(String[] args) {
        int N = 9;
        int[] A = { 0, 0, 0, 0, 1, 1, 1, 2, 2 };
 
        // Function Call
        boolean answer = isPossible(N, A);
        if (answer) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }
    }
}


Python3




# Python code for the above approach
 
# Function to Check if it is possible
# to construct several number
# of arrays from the given array
# satisfying the given condition
def isPossible(N, A):
    # Initialize flag variable to
    # store the answer
    flag = True
 
    # Initializing a dictionary to
    # store frequency of each element
    mp = {}
 
    # Iterating through the array
    for i in range(N):
        # If the current element is less
        # than N, increment
        # its frequency in the dictionary
        if A[i] < N:
            if A[i] in mp:
                mp[A[i]] += 1
            else:
                mp[A[i]] = 1
        # Else, make the value of flag = false
        # (as there can never be more than
        # N elements before any
        # element in the array)
        else:
            flag = False
 
    # Iterate from 1 to N and check the
    # required condition
    for i in range(1, N + 1):
        if i in mp and mp[i] > mp.get(i - 1, 0):
            flag = False
            break
 
    return flag
 
# Driver code
N = 9
A = [0, 0, 0, 0, 1, 1, 1, 2, 2]
 
# Function Call
answer = isPossible(N, A)
if answer:
    print("YES")
else:
    print("NO")
     
# this code is contributed by uttamdp_10


C#




using System;
using System.Collections.Generic;
 
class GFG {
    // Function to Check if it is possible
    // to construct several number
    // of arrays from the given array
    static bool IsPossible(int N, int[] A)
    {
        // Initialize flag variable to
        // store the answer
        bool flag = true;
 
        // Initializing a Dictionary to
        // store frequency of each element
        Dictionary<int, int> map
            = new Dictionary<int, int>();
 
        // Iterating through the array
        for (int i = 0; i < N; i++) {
            // If the current element is less
            // than N, increment
            // its frequency in the dictionary
            if (A[i] < N) {
                if (map.ContainsKey(A[i])) {
                    map[A[i]]++;
                }
                else {
                    map[A[i]] = 1;
                }
            }
 
            // Else, make the value of flag = false
            // (as there can never be more than
            // N elements before any
            // element in the array)
            else {
                flag = false;
            }
        }
 
        // Iterate from 1 to N and check the
        // required condition
        for (int i = 1; i <= N; i++) {
            if (map.TryGetValue(i, out int countI)
                && map.TryGetValue(i - 1,
                                   out int countPrev)) {
                if (countI > countPrev) {
                    flag = false;
                    break;
                }
            }
        }
 
        return flag;
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        int N = 9;
        int[] A = { 0, 0, 0, 0, 1, 1, 1, 2, 2 };
 
        // Function Call
        bool answer = IsPossible(N, A);
        if (answer) {
            Console.WriteLine("YES");
        }
        else {
            Console.WriteLine("NO");
        }
    }
}


Javascript




// Added by: Nikunj Sonigara
 
// Function to check if it's possible to create an array of length N
// with values ranging from 0 to N-1 using the input array A.
function isPossible(N, A) {
    // Initialize a flag as true to assume it's possible.
    let flag = true;
    // Create a Map to store counts of each element.
    const map = new Map();
 
    // Loop through the input array A.
    for (let i = 0; i < N; i++) {
        if (A[i] < N) {
            // Update the count of A[i] in the map.
            map.set(A[i], (map.get(A[i]) || 0) + 1);
        } else {
            // If any element in A is greater than or equal to N, set flag to false.
            flag = false;
        }
    }
 
    // Loop through numbers from 1 to N and check if their counts are non-decreasing.
    for (let i = 1; i <= N; i++) {
        if ((map.get(i) || 0) > (map.get(i - 1) || 0)) {
            // If counts are not non-decreasing, set flag to false.
            flag = false;
            // Exit the loop.
            break;
        }
    }
    // Return the final flag indicating if it's possible.
    return flag;
}
 
// Test input values
const N = 9;
const A = [0, 0, 0, 0, 1, 1, 1, 2, 2];
 
// Call the isPossible function with the test input and print "YES" or "NO" accordingly.
const answer = isPossible(N, A);
if (answer) {
    console.log("YES");
} else {
    console.log("NO");
}


Output

YES













Time Complexity: O(N).
Auxiliary Space: O(N)



Similar Reads

Construction of Longest Increasing Subsequence (N log N)
In my previous post, I have explained about longest increasing sub-sequence (LIS) problem in detail. However, the post only covered code related to querying size of LIS, but not the construction of LIS. I left it as an exercise. If you have solved, cheers. If not, you are not alone, here is code. If you have not read my previous post, read here. No
10 min read
Proto Van Emde Boas Tree | Set 2 | Construction
Van Emde Boas Tree supports search, minimum, maximum, successor, predecessor, insert and delete operations in O(lglgN) time which is faster than any of related data structures like priority queue, binary search tree, etc. Proto Van Emde Boas tree is similar prototype type data structure but it fails to achieve the complexity of O(lglgN), We will le
8 min read
Van Emde Boas Tree | Set 1 | Basics and Construction
It is highly recommended to fully understand Proto Van Emde Boas Tree. Van Emde Boas Tree supports search, successor, predecessor, insert and delete operations in O(lglgN) time which is faster than any of related data structures like priority queue, binary search tree, etc. Van Emde Boas Tree works with O(1) time-complexity for minimum and maximum
9 min read
Maximizing Stick Utilization for Square and Rectangle Construction
Given two arrays A[] and B[] of the same length N. There are N types of sticks of lengths specified. Each stick of length A[i] is present in B[i] units (i=1 to N). You have to construct the squares and rectangles using these sticks. Each unit of a stick can be used as the length or breadth of a rectangle or as a side of a square. A single unit of a
8 min read
Pattern Searching | Set 6 (Efficient Construction of Finite Automata)
In the previous post, we discussed the Finite Automata-based pattern searching algorithm. The FA (Finite Automata) construction method discussed in the previous post takes O((m^3)*NO_OF_CHARS) time. FA can be constructed in O(m*NO_OF_CHARS) time. In this post, we will discuss the O(m*NO_OF_CHARS) algorithm for FA construction. The idea is similar t
9 min read
­­kasai’s Algorithm for Construction of LCP array from Suffix Array
Background Suffix Array : A suffix array is a sorted array of all suffixes of a given string. Let the given string be "banana". 0 banana 5 a1 anana Sort the Suffixes 3 ana2 nana ----------------&gt; 1 anana 3 ana alphabetically 0 banana 4 na 4 na 5 a 2 nanaThe suffix array for "banana" :suffix[] = {5, 3, 1, 0, 4, 2}We have discussed Suffix Array an
21 min read
Construction of Longest Increasing Subsequence(LIS) and printing LIS sequence
The Longest Increasing Subsequence (LIS) problem is to find the length of the longest subsequence of a given sequence such that all elements of the subsequence are sorted in increasing order. Examples: Input: [10, 22, 9, 33, 21, 50, 41, 60, 80]Output: [10, 22, 33, 50, 60, 80] OR [10 22 33 41 60 80] or any other LIS of same length. In the previous p
8 min read
Ukkonen's Suffix Tree Construction - Part 1
Suffix Tree is very useful in numerous string processing and computational biology problems. Many books and e-resources talk about it theoretically and in few places, code implementation is discussed. But still, I felt something is missing and it's not easy to implement code to construct suffix tree and it's usage in many applications. This is an a
8 min read
Ukkonen's Suffix Tree Construction - Part 2
In Ukkonen’s Suffix Tree Construction – Part 1, we have seen high level Ukkonen’s Algorithm. This 2nd part is continuation of Part 1. Please go through Part 1, before looking at current article. In Suffix Tree Construction of string S of length m, there are m phases and for a phase j (1 &lt;= j &lt;= m), we add jth character in tree built so far an
11 min read
Ukkonen's Suffix Tree Construction - Part 3
This article is continuation of following two articles: Ukkonen’s Suffix Tree Construction – Part 1 Ukkonen’s Suffix Tree Construction – Part 2 Please go through Part 1 and Part 2, before looking at current article, where we have seen few basics on suffix tree, high level ukkonen’s algorithm, suffix link and three implementation tricks. Here we wil
15 min read
Article Tags :
Practice Tags :