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
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.
- From the main permutation, the positions of each integer are stored in a map/dictionary.
- 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.
- Their positions also should come as m-consecutive numbers, when sorted, starting with the minimum position/value x, and its m-1 consecutive positions.
- 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.
- 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.
- 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 .
- 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.
C++
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
bool subArray(ll* arr, ll n, ll m)
{
ll i;
unordered_map<ll, ll> mp;
for (i = 0; i < n; i++) {
mp[arr[i]] = i + 1;
}
ll sumcur = 0;
ll p = INT_MAX;
vector<ll> ans;
for (i = 1; i <= m; i++) {
sumcur += mp[i];
p = min(p, mp[i]);
ll val = p * i - i + (i * (i + 1)) / 2;
if (i == m) {
if (val == sumcur) {
return true ;
}
else
return false ;
}
}
}
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
import java.util.*;
class GFG
{
static boolean subArray( int [] arr, int n, int m)
{
int i;
HashMap<Integer, Integer> mp =
new HashMap<Integer, Integer> ();
for (i = 0 ; i < n; i++)
{
mp.put(arr[i], i + 1 );
}
int sumcur = 0 ;
int p = Integer.MAX_VALUE;
Vector<Integer> ans = new Vector<Integer>();
for (i = 1 ; i <= m; i++)
{
sumcur += mp.get(i);
p = Math.min(p, mp.get(i));
int val = p * i - i + (i * (i + 1 )) / 2 ;
if (i == m)
{
if (val == sumcur)
{
return true ;
}
else
return false ;
}
}
return false ;
}
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" );
}
}
|
Python3
def subArray(arr, n, m):
i = 0
mp = dict ()
for i in range (n):
mp[arr[i]] = i + 1
sumcur = 0
p = 10 * * 9
ans = []
for i in range ( 1 , m + 1 ):
sumcur + = mp[i]
p = min (p, mp[i])
val = p * i - i + (i * (i + 1 )) / 2
if (i = = m):
if (val = = sumcur):
return True
else :
return False
arr = [ 4 , 5 , 1 , 3 , 2 , 6 ]
n = len (arr)
m = 3
if (subArray(arr, n, m)):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static bool subArray( int [] arr, int n, int m)
{
int i;
Dictionary< int , int > mp =
new Dictionary< int , int > ();
for (i = 0; i < n; i++)
{
mp.Add(arr[i], i + 1);
}
int sumcur = 0;
int p = int .MaxValue;
List< int > ans = new List< int >();
for (i = 1; i <= m; i++)
{
sumcur += mp[i];
p = Math.Min(p, mp[i]);
int val = p * i - i + (i * (i + 1)) / 2;
if (i == m)
{
if (val == sumcur)
{
return true ;
}
else
return false ;
}
}
return false ;
}
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" );
}
}
|
Javascript
<script>
function subArray(arr, n, m)
{
var i;
var mp = new Map();
for (i = 0; i < n; i++)
{
mp.set(arr[i], i + 1);
}
var sumcur = 0;
var p = 1000000000;
var ans = [];
for (i = 1; i <= m; i++)
{
sumcur += mp.get(i);
p = Math.min(p, mp.get(i));
var val = p * i - i +
parseInt((i * (i + 1)) / 2);
if (i == m)
{
if (val == sumcur)
{
return true ;
}
else
return false ;
}
}
}
var arr = [ 4, 5, 1, 3, 2, 6 ];
var n = arr.length;
var m = 3;
if (subArray(arr, n, m))
document.write( "Yes" );
else
document.write( "No" );
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N) because it is using extra space for map
Another Efficient Approach: Using Sliding Window
We will use a M sized sliding window in which we will keep a count of numbers less than or equal to M and iterate over the array. If the count becomes equal to M, we have found the permutation.
C++
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
bool subArray(ll* arr, ll n, ll m)
{
int count = 0;
for ( int i = 0; i < m; i++){
if (arr[i] <= m)
count++;
}
if (count == m)
return true ;
for ( int i = m; i < n; i++){
if (arr[i-m] <= m)
count--;
if (arr[i] <= m)
count++;
if (count == m)
return true ;
}
return false ;
}
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
import java.io.*;
class GFG {
static boolean subArray( int [] arr, int n, int m)
{
int count = 0 ;
for ( int i = 0 ; i < m; i++) {
if (arr[i] <= m)
count++;
}
if (count == m)
return true ;
for ( int i = m; i < n; i++) {
if (arr[i - m] <= m)
count--;
if (arr[i] <= m)
count++;
if (count == m)
return true ;
}
return false ;
}
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" );
}
}
|
Python3
def subArray(arr, n, m):
count = 0
for i in range (m):
if (arr[i] < = m):
count + = 1
if (count = = m):
return True
for i in range (m,n):
if (arr[i - m] < = m):
count - = 1
if (arr[i] < = m):
count + = 1
if (count = = m):
return True
return False
arr = [ 4 , 5 , 1 , 3 , 2 , 6 ]
n = len (arr)
m = 3
if (subArray(arr, n, m)):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
class GFG {
static bool subArray( int [] arr, int n, int m)
{
int count = 0;
for ( int i = 0; i < m; i++) {
if (arr[i] <= m)
count++;
}
if (count == m)
return true ;
for ( int i = m; i < n; i++) {
if (arr[i - m] <= m)
count--;
if (arr[i] <= m)
count++;
if (count == m)
return true ;
}
return false ;
}
public static void Main()
{
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" );
}
}
|
Javascript
<script>
function subArray(arr, n, m)
{
let count = 0
for (let i = 0; i < m; i++){
if (arr[i] <= m)
count++;
}
if (count == m)
return true ;
for (let i = m; i < n; i++){
if (arr[i-m] <= m)
count--;
if (arr[i] <= m)
count++;
if (count == m)
return true ;
}
return false ;
}
let arr =[ 4, 5, 1, 3, 2, 6 ]
let n = arr.length
let m = 3
if (subArray(arr, n, m))
document.write( "Yes" )
else
document.write( "No" )
</script>
|
Time Complexity: O(N)
Space Complexity: O(N)
Last Updated :
24 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...