Subarray permutation that satisfies the given condition

Given a permutation of integers from 1 to N and an integer M, the task is to check if any subarray of the given permutation is a permutation of the integers from 1 to M.

Examples:

Input: arr[] = {4, 5, 1, 3, 2, 6}, M = 3
Output: Yes
{4, 5, 1, 3, 2, 6} is the required subarray.

Input: arr[] = {4, 5, 1, 3, 2, 6}, M = 4
Output: No

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive approach: A naive approach would be to generate all the M-sized subarrays and see if any such subarray exists. But if the given permutation is too large, this approach will be time-consuming as it runs in O(N3).

Efficient approach: A better solution is to use Hashing.

1. From the main permutation, the positions of each integer are stored in a map/dictionary.
2. Now, observe that if there exists a subarray which is a permutation from 1 to m, then all numbers in range [1, m] will occupy m consecutive places in the main permutation, either in a sorted or random manner.
3. Their positions also should come as m-consecutive numbers, when sorted, starting with the minimum position/value x, and its m-1 consecutive positions.
4. Therefore the ‘sum of positions’ for each integer 1 to n can be calculated, where sum_of_position(k) = sumcur= Position_of_1 + Position_of_2 + …Position_of_k.
5. Let the minimum element of the above series be x. When the positions are sorted, this will be the first element and the rest will be consecutive.
6. Then if the required subarray exists, then sum_of_position(m) has to be x + (x+1) + ..(x+m-1) {m consecutive terms} = x*m – m + m*(m+1)/2 .
7. If sum of all positions for integers 1 to m is this sum, then for given m, true is returned, else there is no such sub-array.

Below is the implementation of the above approach.

CPP

 `// C++ implementation of the approach ` `#include ` `using` `namespace` `std; ` ` `  `typedef` `long` `long` `int` `ll; ` ` `  `// Function that returns true if the ` `// required subarray exists ` `// in the given array ` `bool` `subArray(ll* arr, ll n, ll m) ` `{ ` `    ``ll i; ` ` `  `    ``// Map to store the positions of ` `    ``// each integer in the original ` `    ``// permutation ` `    ``unordered_map mp; ` `    ``for` `(i = 0; i < n; i++) { ` ` `  `        ``// To store the address of each ` `        ``// entry in arr[n] but with ` `        ``// 1-based indexing ` `        ``mp[arr[i]] = i + 1; ` `    ``} ` ` `  `    ``ll sumcur = 0; ` ` `  `    ``// To track minimum position sumcur ` `    ``// for sum of all positions ` `    ``// till this position ` `    ``ll p = INT_MAX; ` `    ``vector ans; ` `    ``for` `(i = 1; i <= m; i++) { ` ` `  `        ``// Summing up addresses ` `        ``sumcur += mp[i]; ` ` `  `        ``// Tracking minimum address ` `        ``// encountered till now ` `        ``p = min(p, mp[i]); ` ` `  `        ``// The sum of the addresses if ` `        ``// it forms the required subarray ` `        ``ll val = p * i - i + (i * (i + 1)) / 2; ` `        ``if` `(i == m) { ` ` `  `            ``// If current sum of address ` `            ``// is equal to val ` `            ``if` `(val == sumcur) { ` `                ``return` `true``; ` `            ``} ` `            ``else` `                ``return` `false``; ` `        ``} ` `    ``} ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` `    ``ll arr[] = { 4, 5, 1, 3, 2, 6 }; ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(``int``); ` `    ``ll m = 3; ` ` `  `    ``if` `(subArray(arr, n, m)) ` `        ``cout << ``"Yes"``; ` `    ``else` `        ``cout << ``"No"``; ` ` `  `    ``return` `0; ` `} `

Java

 `// Java implementation of the approach ` `import` `java.util.*; ` ` `  `class` `GFG ` `{ ` ` `  `// Function that returns true if the ` `// required subarray exists ` `// in the given array ` `static` `boolean` `subArray(``int``[] arr, ``int` `n, ``int` `m) ` `{ ` `    ``int` `i; ` ` `  `    ``// Map to store the positions of ` `    ``// each integer in the original ` `    ``// permutation ` `    ``HashMap mp =  ` `        ``new` `HashMap (); ` `    ``for` `(i = ``0``; i < n; i++)  ` `    ``{ ` ` `  `        ``// To store the address of each ` `        ``// entry in arr[n] but with ` `        ``// 1-based indexing ` `        ``mp.put(arr[i], i + ``1``); ` `    ``} ` ` `  `    ``int` `sumcur = ``0``; ` ` `  `    ``// To track minimum position sumcur ` `    ``// for sum of aint positions ` `    ``// tiint this position ` `    ``int` `p = Integer.MAX_VALUE; ` `    ``Vector ans = ``new` `Vector(); ` `    ``for` `(i = ``1``; i <= m; i++)  ` `    ``{ ` ` `  `        ``// Summing up addresses ` `        ``sumcur += mp.get(i); ` ` `  `        ``// Tracking minimum address ` `        ``// encountered tiint now ` `        ``p = Math.min(p, mp.get(i)); ` ` `  `        ``// The sum of the addresses if ` `        ``// it forms the required subarray ` `        ``int` `val = p * i - i + (i * (i + ``1``)) / ``2``; ` `        ``if` `(i == m) ` `        ``{ ` ` `  `            ``// If current sum of address ` `            ``// is equal to val ` `            ``if` `(val == sumcur) ` `            ``{ ` `                ``return` `true``; ` `            ``} ` `            ``else` `                ``return` `false``; ` `        ``} ` `    ``} ` `    ``return` `false``; ` `} ` ` `  `// Driver code ` `public` `static` `void` `main(String[] args) ` `{ ` `    ``int` `arr[] = { ``4``, ``5``, ``1``, ``3``, ``2``, ``6` `}; ` `    ``int` `n = arr.length; ` `    ``int` `m = ``3``; ` ` `  `    ``if` `(subArray(arr, n, m)) ` `        ``System.out.print(``"Yes"``); ` `    ``else` `        ``System.out.print(``"No"``); ` `} ` `} ` ` `  `// This code is contributed by Rajput-Ji `

Python3

 `# Python3 implementation of the approach ` ` `  `# Function that returns true if the ` `# required subarray exists ` `# in the given array ` `def` `subArray(arr, n, m): ` `    ``i ``=` `0` ` `  `    ``# Map to store the positions of ` `    ``# each integer in the original ` `    ``# permutation ` `    ``mp ``=` `dict``() ` `    ``for` `i ``in` `range``(n): ` `         `  `        ``# To store the address of each ` `        ``# entry in arr[n] but with ` `        ``# 1-based indexing ` `        ``mp[arr[i]] ``=` `i ``+` `1` ` `  `    ``sumcur ``=` `0` ` `  `    ``# To track minimum position sumcur ` `    ``# for sum of a positions ` `    ``# ti this position ` `    ``p ``=` `10``*``*``9` `    ``ans ``=` `[] ` `    ``for` `i ``in` `range``(``1``, m ``+` `1``): ` ` `  `        ``# Summing up addresses ` `        ``sumcur ``+``=` `mp[i] ` ` `  `        ``# Tracking minimum address ` `        ``# encountered ti now ` `        ``p ``=` `min``(p, mp[i]) ` ` `  `        ``# The sum of the addresses if ` `        ``# it forms the required subarray ` `        ``val ``=` `p ``*` `i ``-` `i ``+` `(i ``*` `(i ``+` `1``)) ``/` `2` `        ``if` `(i ``=``=` `m): ` ` `  `            ``# If current sum of address ` `            ``# is equal to val ` `            ``if` `(val ``=``=` `sumcur): ` `                ``return` `True` `            ``else``: ` `                ``return` `False` ` `  `# Driver code ` ` `  `arr ``=` `[``4``, ``5``, ``1``, ``3``, ``2``, ``6``] ` `n ``=` `len``(arr) ` `m ``=` `3` ` `  `if` `(subArray(arr, n, m)): ` `    ``print``(``"Yes"``) ` `else``: ` `    ``print``(``"No"``) ` ` `  `# This code is contributed by mohit kumar 29 `

C#

 `// C# implementation of the approach ` `using` `System; ` `using` `System.Collections.Generic; ` ` `  `class` `GFG ` `{ ` ` `  `// Function that returns true if the ` `// required subarray exists ` `// in the given array ` `static` `bool` `subArray(``int``[] arr, ``int` `n, ``int` `m) ` `{ ` `    ``int` `i; ` ` `  `    ``// Map to store the positions of ` `    ``// each integer in the original ` `    ``// permutation ` `    ``Dictionary<``int``, ``int``> mp =  ` `        ``new` `Dictionary<``int``, ``int``> (); ` `    ``for` `(i = 0; i < n; i++)  ` `    ``{ ` ` `  `        ``// To store the address of each ` `        ``// entry in arr[n] but with ` `        ``// 1-based indexing ` `        ``mp.Add(arr[i], i + 1); ` `    ``} ` ` `  `    ``int` `sumcur = 0; ` ` `  `    ``// To track minimum position sumcur ` `    ``// for sum of aint positions ` `    ``// tiint this position ` `    ``int` `p = ``int``.MaxValue; ` `    ``List<``int``> ans = ``new` `List<``int``>(); ` `    ``for` `(i = 1; i <= m; i++)  ` `    ``{ ` ` `  `        ``// Summing up addresses ` `        ``sumcur += mp[i]; ` ` `  `        ``// Tracking minimum address ` `        ``// encountered tiint now ` `        ``p = Math.Min(p, mp[i]); ` ` `  `        ``// The sum of the addresses if ` `        ``// it forms the required subarray ` `        ``int` `val = p * i - i + (i * (i + 1)) / 2; ` `        ``if` `(i == m) ` `        ``{ ` ` `  `            ``// If current sum of address ` `            ``// is equal to val ` `            ``if` `(val == sumcur) ` `            ``{ ` `                ``return` `true``; ` `            ``} ` `            ``else` `                ``return` `false``; ` `        ``} ` `    ``} ` `    ``return` `false``; ` `} ` ` `  `// Driver code ` `public` `static` `void` `Main(String[] args) ` `{ ` `    ``int` `[]arr = { 4, 5, 1, 3, 2, 6 }; ` `    ``int` `n = arr.Length; ` `    ``int` `m = 3; ` ` `  `    ``if` `(subArray(arr, n, m)) ` `        ``Console.Write(``"Yes"``); ` `    ``else` `        ``Console.Write(``"No"``); ` `} ` `} ` ` `  `// This code is contributed by 29AjayKumar `

Output:

```Yes
```

Time Complexity: O(N)

My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Article Tags :
Practice Tags :

1

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.