 GFG App
Open App Browser
Continue

# Check if Array elements of given range form a permutation

Given an array arr[] consisting of N distinct integers and an array Q[] consisting of M queries of the form [L, R], the task for each query is to check if array elements over the range [L, R] forms a permutation or not.

Note: A permutation is a sequence of length N containing each number from 1 to N exactly once. For example, (1), (4,  3,  5,  1,  2) are permutations, and (1,  1), (4,  3,  1) are not.

Examples:

Input: arr[] = {6, 4, 1, 2, 3, 5, 7}, Q[][] = {{2, 4}, {0, 4}, {1, 5}}
Output:
YES
NO
YES
Explanation: Query 1: The elements of the array over the range [2, 4] are {1, 2, 3} which forms a permutation. Hence, print “YES”.
Query 2: The elements of the array over the range [0, 4] are {6, 4, 1, 2} which does not forms an permutation. Hence, print “NO”.
Query 3: The elements of the array over the range [1, 5] are {4, 1, 2, 3, 5}, which form an permutation. Hence, print “YES”.

Input: arr[] = {1, 2, 4, 3, 9}, Q[][] = {{0, 3}, {0, 4}}
Output:
YES
NO

Naive Approach: The basic way to solve the problem is as follows:

Traverse the given array over the range [L, R] for each query and check if every element is present or not from 1 to R – L + 1. This can be done by taking the sum of all elements from L to R if it is equal to the sum of 1 + 2 + 3 + 4 + . . . . + size of subarray [L, R], then print “YES”. Otherwise, print “NO”.

Time Complexity: O(N * M)
Auxiliary Space: O(1)

Efficient Approach:  The above approach can be optimized based on the following idea:

The idea is rather than calculating the sum of elements from L to R for each query precomputation can be done using the prefix sum. For Each query Q sum from L to R can be found in O(1) time using prefix sum.

The sum from 1 + 2 + 3 + 4 + . . . + size of subarray [L, R] can be found using the number theory formula for finding the sum of the first n natural numbers which is n * (n + 1) / 2

Follow the steps below to solve the problem:

• Initialize an array (say prefix[]) to store the prefix sum of the array
• To fill the prefix sum array, we run through index 1 to N and keep on adding the present element with the previous value in the prefix sum array.
• Traverse the given array of queries Q[] and for each query {L, R}.
• Initiate the size variable and fill with R – L + 1 which is the size of the subarray [L, R].
• Initiate the total_From_1_To_Size variable whose value will fill with n * ( n + 1) / 2.
• Initiate the variable total_From_L_To_R whose value will be found using precomputed array prefix[].
• If total_From_L_To_R and total_From_1_To_Size are equal then print “YES” else print “NO“.

Below is the implementation of the above approach:

## C++

 `// C++ code to implement the approach`   `#include ` `using` `namespace` `std;`   `// Function to check if the given range` `// of queries form an Permutation or not` `// in the given array arr[]` `void` `findPermutation(``int` `arr[], ``int` `N,` `                     ``int` `Q[], ``int` `M)` `{` `    ``// Precomputation array` `    ``// stores the sum of all ranges` `    ``// for any L to R` `    ``int` `prefix[N + 1] = { 0 };`   `    ``// Iterates over the range [1, N]` `    ``for` `(``int` `i = 1; i <= N; i++) {`   `        ``// Finding prefix sum of` `        ``// given array` `        ``prefix[i] = prefix[i - 1] + arr[i - 1];` `    ``}`   `    ``// Traverse the given queries` `    ``for` `(``int` `i = 0; i < M; i++) {`   `        ``// Stores range L to R for` `        ``// each query` `        ``int` `L = Q[i], R = Q[i];`   `        ``// Size variable stores size of` `        ``// [L, R] range` `        ``int` `size = R - L + 1;`   `        ``// Stores total from 1 to size of` `        ``// range [L, R]` `        ``int` `total_From_1_To_Size` `            ``= size * (size + 1) / 2;`   `        ``// Stores total sum from L to R` `        ``// of Array` `        ``int` `total_From_L_To_R` `            ``= prefix[R] - prefix[L - 1];`   `        ``// If total from 1 to size is equal` `        ``// to total from L to R then print` `        ``// yes` `        ``if` `(total_From_L_To_R == total_From_1_To_Size) {` `            ``cout << ``"YES"` `<< endl;` `        ``}` `        ``else` `{` `            ``cout << ``"NO"` `<< endl;` `        ``}` `    ``}` `}`   `// Driver Code` `int` `main()` `{` `    ``int` `arr[] = { 6, 4, 1, 2, 3, 5, 7 };` `    ``int` `Q[] = { { 3, 5 }, { 1, 5 }, { 2, 6 } };` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``int` `M = ``sizeof``(Q) / ``sizeof``(Q);`   `    ``// Function Call` `    ``findPermutation(arr, N, Q, M);`   `    ``return` `0;` `}`

## Java

 `// Java code to implement the approach` `import` `java.io.*;`   `class` `GFG {` `    ``// Function to check if the given range` `    ``// of queries form an Permutation or not` `    ``// in the given array arr[]` `    ``public` `static` `void` `findPermutation(``int` `arr[], ``int` `N,` `                                       ``int` `Q[][], ``int` `M)` `    ``{` `        ``// Precomputation array` `        ``// stores the sum of all ranges` `        ``// for any L to R` `        ``int` `prefix[] = ``new` `int``[N + ``1``];`   `        ``// Iterates over the range [1, N]` `        ``for` `(``int` `i = ``1``; i <= N; i++) {`   `            ``// Finding prefix sum of` `            ``// given array` `            ``prefix[i] = prefix[i - ``1``] + arr[i - ``1``];` `        ``}`   `        ``// Traverse the given queries` `        ``for` `(``int` `i = ``0``; i < M; i++) {`   `            ``// Stores range L to R for` `            ``// each query` `            ``int` `L = Q[i][``0``], R = Q[i][``1``];`   `            ``// Size variable stores size of` `            ``// [L, R] range` `            ``int` `size = R - L + ``1``;`   `            ``// Stores total from 1 to size of` `            ``// range [L, R]` `            ``int` `total_From_1_To_Size` `                ``= size * (size + ``1``) / ``2``;`   `            ``// Stores total sum from L to R` `            ``// of Array` `            ``int` `total_From_L_To_R` `                ``= prefix[R] - prefix[L - ``1``];`   `            ``// If total from 1 to size is equal` `            ``// to total from L to R then print` `            ``// yes` `            ``if` `(total_From_L_To_R == total_From_1_To_Size) {` `                ``System.out.println(``"YES"``);` `            ``}` `            ``else` `{` `                ``System.out.println(``"NO"``);` `            ``}` `        ``}` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int` `arr[] = { ``6``, ``4``, ``1``, ``2``, ``3``, ``5``, ``7` `};` `        ``int` `Q[][] = { { ``3``, ``5` `}, { ``1``, ``5` `}, { ``2``, ``6` `} };` `        ``int` `N = arr.length;` `        ``int` `M = Q.length;`   `        ``// Function Call` `        ``findPermutation(arr, N, Q, M);` `    ``}` `}`   `// This code is contributed by Rohit Pradhan`

## Python3

 `# Python code to implement the approach`   `# Function to check if the given range` `# of queries form an Permutation or not` `# in the given array arr[]` `def` `findPermutation(arr, N, Q, M) :`   `    ``# Precomputation array` `    ``# stores the sum of all ranges` `    ``# for any L to R` `    ``prefix ``=` `[``0``] ``*` `(N ``+` `1``)`   `    ``# Iterates over the range [1, N]` `    ``for` `i ``in` `range``(``1``, N``+``1``):`   `        ``# Finding prefix sum of` `        ``# given array` `        ``prefix[i] ``=` `prefix[i ``-` `1``] ``+` `arr[i ``-` `1``]` `    `    `    ``# Traverse the given queries` `    ``for` `i ``in` `range``(``0``, M):`   `        ``# Stores range L to R for` `        ``# each query` `        ``L ``=` `Q[i][``0``]` `        ``R ``=` `Q[i][``1``]`   `        ``# Size variable stores size of` `        ``# [L, R] range` `        ``size ``=` `R ``-` `L ``+` `1`   `        ``# Stores total from 1 to size of` `        ``# range [L, R]` `        ``total_From_1_To_Size ``=` `size ``*` `(size ``+` `1``) ``/``/` `2`   `        ``# Stores total sum from L to R` `        ``# of Array` `        ``total_From_L_To_R ``=` `prefix[R] ``-` `prefix[L ``-` `1``]`   `        ``# If total from 1 to size is equal` `        ``# to total from L to R then print` `        ``# yes` `        ``if` `(total_From_L_To_R ``=``=` `total_From_1_To_Size) :` `            ``print``(``"YES"``)` `        `  `        ``else` `:` `            ``print``(``"NO"``)` `        `  `# Driver Code` `if` `__name__ ``=``=` `"__main__"``:`   `    ``arr ``=` `[ ``6``, ``4``, ``1``, ``2``, ``3``, ``5``, ``7` `]` `    ``Q ``=` `[[ ``3``, ``5` `], [ ``1``, ``5` `], [ ``2``, ``6``]]  ` `    ``N ``=` `len``(arr) ` `    ``M ``=` `len``(Q) `   `    ``# Function Call` `    ``findPermutation(arr, N, Q, M)` `    `  `    ``# This code is contributed by sanjoy_62.`

## C#

 `// C# code to implement the approach`   `using` `System;`   `public` `class` `GFG {`   `    ``// Function to check if the given range` `    ``// of queries form an Permutation or not` `    ``// in the given array arr[]` `    ``public` `static` `void` `findPermutation(``int``[] arr, ``int` `N,` `                                       ``int``[, ] Q, ``int` `M)` `    ``{` `        ``// Precomputation array` `        ``// stores the sum of all ranges` `        ``// for any L to R` `        ``int``[] prefix = ``new` `int``[N + 1];`   `        ``// Iterates over the range [1, N]` `        ``for` `(``int` `i = 1; i <= N; i++) {`   `            ``// Finding prefix sum of` `            ``// given array` `            ``prefix[i] = prefix[i - 1] + arr[i - 1];` `        ``}`   `        ``// Traverse the given queries` `        ``for` `(``int` `i = 0; i < M; i++) {`   `            ``// Stores range L to R for` `            ``// each query` `            ``int` `L = Q[i, 0], R = Q[i, 1];`   `            ``// Size variable stores size of` `            ``// [L, R] range` `            ``int` `size = R - L + 1;`   `            ``// Stores total from 1 to size of` `            ``// range [L, R]` `            ``int` `total_From_1_To_Size` `                ``= size * (size + 1) / 2;`   `            ``// Stores total sum from L to R` `            ``// of Array` `            ``int` `total_From_L_To_R` `                ``= prefix[R] - prefix[L - 1];`   `            ``// If total from 1 to size is equal` `            ``// to total from L to R then print` `            ``// yes` `            ``if` `(total_From_L_To_R == total_From_1_To_Size) {` `                ``Console.WriteLine(``"YES"``);` `            ``}` `            ``else` `{` `                ``Console.WriteLine(``"NO"``);` `            ``}` `        ``}` `    ``}`   `    ``static` `public` `void` `Main()` `    ``{`   `        ``// Code` `        ``int``[] arr = { 6, 4, 1, 2, 3, 5, 7 };` `        ``int``[, ] Q = { { 3, 5 }, { 1, 5 }, { 2, 6 } };` `        ``int` `N = arr.Length;` `        ``int` `M = Q.GetLength(0);`   `        ``// Function Call` `        ``findPermutation(arr, N, Q, M);` `    ``}` `}`   `// This code is contributed by lokeshmvs21.`

## Javascript

 `// JavaScript code to implement the approach`   `// Function to check if the given range` `// of queries form an Permutation or not` `// in the given array arr[]` `const findPermutation = (arr, N, Q, M) => {` `    ``// Precomputation array` `    ``// stores the sum of all ranges` `    ``// for any L to R` `    ``let prefix = ``new` `Array(N + 1).fill(0);`   `    ``// Iterates over the range [1, N]` `    ``for` `(let i = 1; i <= N; i++) {`   `        ``// Finding prefix sum of` `        ``// given array` `        ``prefix[i] = prefix[i - 1] + arr[i - 1];` `    ``}`   `    ``// Traverse the given queries` `    ``for` `(let i = 0; i < M; i++) {`   `        ``// Stores range L to R for` `        ``// each query` `        ``let L = Q[i], R = Q[i];`   `        ``// Size variable stores size of` `        ``// [L, R] range` `        ``let size = R - L + 1;`   `        ``// Stores total from 1 to size of` `        ``// range [L, R]` `        ``let total_From_1_To_Size` `            ``= size * parseInt((size + 1) / 2);`   `        ``// Stores total sum from L to R` `        ``// of Array` `        ``let total_From_L_To_R` `            ``= prefix[R] - prefix[L - 1];`   `        ``// If total from 1 to size is equal` `        ``// to total from L to R then print` `        ``// yes` `        ``if` `(total_From_L_To_R == total_From_1_To_Size) {` `            ``console.log(``"YES
"``);` `        ``}` `        ``else` `{` `            ``console.log(``"NO
"``);` `        ``}` `    ``}` `}`   `// Driver Code`   `let arr = [6, 4, 1, 2, 3, 5, 7];` `let Q = [[3, 5], [1, 5], [2, 6]];` `let N = arr.length;` `let M = Q.length;`   `// Function Call` `findPermutation(arr, N, Q, M);`   `// This code is contributed by rakeshsahni`

Output

```YES
NO
YES```

Time Complexity: O(N + M)
Auxiliary Space: O(N)

### Using Sorting in python:

Approach:

Define a function is_permutation that takes three arguments: arr, left, and right.
Extract the range from the array arr using the left and right indices.
Sort the range using the .sort() method.
Check if the sorted range forms a permutation by iterating over it and comparing each element to its expected value (i.e., i+1 where i is the index of the element in the range).
If any element does not match its expected value, return “NO”.
If all elements match their expected values, return “YES”.
Define the array arr and the queries queries.
Iterate over the queries and call the is_permutation function for each query, passing in the relevant indices.
Print the result of each query.

## Python3

 `def` `is_permutation(arr, left, right):` `    ``# extract the range from the array` `    ``range_arr ``=` `arr[left:right``+``1``]` `    ``# sort the range` `    ``range_arr.sort()` `    ``# check if the sorted range forms a permutation` `    ``for` `i ``in` `range``(``len``(range_arr)):` `        ``if` `range_arr[i] !``=` `i``+``1``:` `            ``return` `"NO"` `    ``return` `"YES"`   `arr ``=` `[``1``, ``2``, ``4``, ``3``, ``9``]` `queries ``=` `[[``0``, ``3``], [``0``, ``4``]]`   `for` `query ``in` `queries:` `    ``print``(is_permutation(arr, query[``0``], query[``1``]))`

Output

```YES
NO```

Time Complexity: O(n*log(n)) for each query
Auxiliary Space: O(n) for storing the sorted range

My Personal Notes arrow_drop_up