Open In App

Subarray permutation that satisfies the given condition

Improve
Improve
Like Article
Like
Save
Share
Report

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.  

  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.  

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
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<ll, ll> 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<ll> 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<Integer, Integer> mp =
        new HashMap<Integer, Integer> ();
    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 all positions
    // tiint this position
    int p = Integer.MAX_VALUE;
    Vector<Integer> ans = new Vector<Integer>();
    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 all 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 all 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


Javascript




<script>
 
// Javascript implementation of the approach
 
// Function that returns true if the
// required subarray exists
// in the given array
function subArray(arr, n, m)
{
    var i;
 
    // Map to store the positions of
    // each integer in the original
    // permutation
    var mp = new Map();
    for(i = 0; i < n; i++)
    {
         
        // To store the address of each
        // entry in arr[n] but with
        // 1-based indexing
        mp.set(arr[i], i + 1);
    }
 
    var sumcur = 0;
 
    // To track minimum position sumcur
    // for sum of all positions
    // till this position
    var p = 1000000000;
    var ans = [];
    for(i = 1; i <= m; i++)
    {
         
        // Summing up addresses
        sumcur += mp.get(i);
 
        // Tracking minimum address
        // encountered till now
        p = Math.min(p, mp.get(i));
 
        // The sum of the addresses if
        // it forms the required subarray
        var val = p * i - i +
        parseInt((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
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");
     
// This code is contributed by famously
 
</script>


Output: 

Yes

 

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++




// C++ implementation of the approach
#include <bits/stdc++.h>
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)
{
    int count = 0;//count less than m
      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;
}
  
// 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.io.*;
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 count = 0; // count less than m
    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;
  }
 
  // 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 subhammahato348.


Python3




# Python3 implementation of the approach
 
# Function that returns true if the
# required subarray exists
# in the given array
def subArray(arr, n, m):
 
    count = 0 # count less than m
    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
  
# 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 shinjanpatra


C#




// C# implementation of the approach
using System;
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 count = 0; // count less than m
    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;
  }
 
  // Driver code
  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");
  }
}
 
// This code is contributed by subhammahato348.


Javascript




<script>
 
// JavaScript implementation of the approach
 
// Function that returns true if the
// required subarray exists
// in the given array
function subArray(arr, n, m)
{
    let count = 0//count less than m
    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;
}
  
// Driver code
 
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")
 
// This code is contributed by shinjanpatra
 
</script>


Time Complexity: O(N)

Space Complexity: O(N)



Last Updated : 24 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads