# Check if Array elements of given range form a permutation

• Difficulty Level : Hard
• Last Updated : 01 Dec, 2022

Given an array arr[] consisting of N distinct integers and an array Q[][2] 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 <bits/stdc++.h>
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[][2], 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][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) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
}

// Driver Code
int main()
{
int arr[] = { 6, 4, 1, 2, 3, 5, 7 };
int Q[][2] = { { 3, 5 }, { 1, 5 }, { 2, 6 } };
int N = sizeof(arr) / sizeof(arr[0]);
int M = sizeof(Q) / sizeof(Q[0]);

// 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][0], R = Q[i][1];

// 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<br/>");
}
else {
console.log("NO<br/>");
}
}
}

// 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)

My Personal Notes arrow_drop_up