Open In App

Check if elements of given array can be rearranged such that (arr[i] + i*K) % N = i for all values of i in range [0, N-1]

Given an array arr[] consisting of N positive integers and an integer K, the task is to check if the array elements can be rearranged such that (arr[i] + i*K) % N = i for all values of i in the range [0, N-1].

Examples:



Input: arr[] = {2, 1, 0}, K = 5
Output: Yes
Explanation: The given array can be rearranged to {0, 2, 1}. Hence the values after updation becomes {(0 + 0*5) % 3, (2 + 1*5) % 3, (1 + 2*5) % 3} => {0%3, 7%3, 11%3} => {0, 1, 2} having all elements equal to their indices in the array. 

Input: arr[] = {1, 1, 1, 1, 1}, K = 5
Output: No



 

Naive Approach: The given problem can be solved by generating all the possible permutations of the given array arr[] and check if there exists any such permutation that satisfies the given criteria.

Time Complexity: O(N*N!)
Auxiliary Space: O(N)

Efficient Approach: The above approach can also be optimized with the help of the Set data structure using Recursion. Below are a few observations to solve the given problem:

Using the above observations, the given problem can be solved by the following steps:

Below is the implementation of the above approach:




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if it is possible
// to generate all numbers in range
// [0, N-1] using the sum of elements
// in the multiset A and B mod N
bool isPossible(multiset<int> A,
                multiset<int> B,
                set<int> C, int N)
{
    // If no more pair of elements
    // can be selected
    if (A.size() == 0 || B.size() == 0) {
 
        // If the number of elements
        // in C = N, then return true
        if (C.size() == N) {
            return true;
        }
 
        // Otherwise return false
        else {
            return false;
        }
    }
 
    // Stores the value of final answer
    bool ans = false;
 
    // Iterate through all the pairs in
    // the given multiset A and B
    for (auto x : A) {
        for (auto y : B) {
 
            // Stores the set A without x
            multiset<int> _A = A;
            _A.erase(_A.find(x));
 
            // Stores the set B without y
            multiset<int> _B = B;
            _B.erase(_B.find(y));
 
            // Stores the set C with (x+y)%N
            set<int> _C = C;
            _C.insert((x + y) % N);
 
            // Recursive call
            ans = (ans
                   || isPossible(
                          _A, _B, _C, N));
        }
    }
 
    // Return Answer
    return ans;
}
 
// Function to check if it is possible
// to rearrange array elements such that
// (arr[i] + i*K) % N = i
void rearrangeArray(
    int arr[], int N, int K)
{
    // Stores the values of arr[] modulo N
    multiset<int> A;
    for (int i = 0; i < N; i++) {
        A.insert(arr[i] % N);
    }
 
    // Stores all the values of
    // i*K modulo N
    multiset<int> B;
    for (int i = 0; i < N; i++) {
        B.insert((i * K) % N);
    }
 
    set<int> C;
 
    // Print Answer
    if (isPossible(A, B, C, N)) {
        cout << "YES";
    }
    else {
        cout << "NO";
    }
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 2, 0 };
    int K = 5;
    int N = sizeof(arr) / sizeof(arr[0]);
 
    rearrangeArray(arr, N, K);
 
    return 0;
}




import java.util.ArrayList;
import java.util.HashSet;
 
class Main {
 
    // Function to check if it is possible
    // to generate all numbers in range
    // [0, N-1] using the sum of elements
    // in the multiset A and B mod N
    public static boolean isPossible(ArrayList<Integer> A,
                                     ArrayList<Integer> B, HashSet<Integer> C,
                                     int N) {
 
        // If no more pair of elements
        // can be selected
        if (A.size() == 0 || B.size() == 0) {
 
            // If the number of elements
            // in C = N, then return true
            if (C.size() == N) {
                return true;
            }
 
            // Otherwise return false
            else {
                return false;
            }
        }
 
        // Stores the value of final answer
        boolean ans = false;
 
        // Iterate through all the pairs in
        // the given multiset A and B
        for (Integer x : A) {
            for (Integer y : B) {
 
                // Stores the set A without x
                ArrayList<Integer> _A = new ArrayList<Integer>(A);
                _A.remove(x);
 
                // Stores the set B without y
                ArrayList<Integer> _B = new ArrayList<Integer>(B);
                _B.remove(y);
 
                // Stores the set C with (x+y)%N
                HashSet<Integer> _C = new HashSet<Integer>(C);
                _C.add((x + y) % N);
 
                // Recursive call
                ans = (ans
                        || isPossible(_A, _B, _C, N));
            }
        }
 
        // Return Answer
        return ans;
    }
 
    // Function to check if it is possible
    // to rearrange array elements such that
    // (arr[i] + i*K) % N = i
    public static void rearrangeArray(
            int arr[], int N, int K)
    {
        // Stores the values of arr[] modulo N
        ArrayList<Integer> A = new ArrayList<Integer>();
        for (int i = 0; i < N; i++) {
            A.add(arr[i] % N);
        }
 
        // Stores all the values of
        // i*K modulo N
        ArrayList<Integer> B = new ArrayList<Integer>();
        for (int i = 0; i < N; i++) {
            B.add((i * K) % N);
        }
 
        HashSet<Integer> C = new HashSet<Integer>();
 
        // Print Answer
        if (isPossible(A, B, C, N)) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }
    }
 
    // Driver Code
    public static void main(String[] args) {
        int arr[] = {1, 2, 0};
        int K = 5;
        int N = arr.length;
 
        rearrangeArray(arr, N, K);
    }
}




# Python3 program for the above approach
 
# Function to check if it is possible
# to generate all numbers in range
# [0, N-1] using the sum of elements
#+ in the multiset A and B mod N
def isPossible(A, B, C, N):
   
     # If no more pair of elements
    # can be selected
    if(len(A) == 0 or len(B) == 0):
       
         # If the number of elements
        # in C = N, then return true
        if(len(C) == N):
            return True
           
        # Otherwise return false
        else:
            return False
           
    # Stores the value of final answer
    ans = False
    for x in A:
       
        # Iterate through all the pairs in
        # the given multiset A and B
        for y in B:
           
           # Stores the set A without x
            _A = A
            _A.remove(x)
             
            # Stores the set A without y
            _B = B
            _B.remove(y)
             
             # Stores the set A without x+y%N
            _C = C
            _C.add((x+y) % N)
             
            # Recursive call
             
            ans = (ans or isPossible(_A, _B, _C, N))
             
    return ans
 
# Function to check if it is possible
# to rearrange array elements such that
# (arr[i] + i*K) % N = i
def rearrangeArray(arr, N, K):
   
   # Stores the values of arr[] modulo N
    A = []
    for i in range(N):
        A.append(arr[i] % N)
    A.sort()
     
     # Stores all the values of
    # i*K modulo N
    B = []
    for i in range(N):
        B.append((i*K) % N)
    B.sort()
    C = set()
     
    # Print Answer
    if isPossible(A, B, C, N):
        print("YES")
    else:
        print("NO")
 
# Driver code
arr = [1, 2, 0]
K = 5
N = len(arr)
rearrangeArray(arr, N, K)
 
# This code is contributed by parthmanchanda81




using System;
using System.Collections.Generic;
 
class GFG
{
 
  // Function to check if it is possible to generate all
  // numbers in range [0, N-1] using the sum of elements
  // in the multiset A and B mod N
  public static bool IsPossible(List<int> A, List<int> B,
                                HashSet<int> C, int N)
  {
 
    // If no more pair of elements can be selected
    if (A.Count == 0 || B.Count == 0)
    {
 
      // If the number of elements in C = N, then
      // return true
      if (C.Count == N) {
        return true;
      }
      // Otherwise return false
      else {
        return false;
      }
    }
 
    // Stores the value of final answer
    bool ans = false;
 
    // Iterate through all the pairs in the given
    // multiset A and B
    foreach(int x in A)
    {
      foreach(int y in B)
      {
        // Stores the set A without x
        List<int> _A = new List<int>(A);
        _A.Remove(x);
 
        // Stores the set B without y
        List<int> _B = new List<int>(B);
        _B.Remove(y);
 
        // Stores the set C with (x + y) % N
        HashSet<int> _C = new HashSet<int>(C);
        _C.Add((x + y) % N);
 
        // Recursive call
        ans = (ans || IsPossible(_A, _B, _C, N));
      }
    }
 
    // Return Answer
    return ans;
  }
 
  // Function to check if it is possible to rearrange
  // array elements such that (arr[i] + i * K) % N = i
  public static void RearrangeArray(int[] arr, int N,
                                    int K)
  {
    // Stores the values of arr[] modulo N
    List<int> A = new List<int>();
    for (int i = 0; i < N; i++) {
      A.Add(arr[i] % N);
    }
 
    // Stores all the values of i * K modulo N
    List<int> B = new List<int>();
    for (int i = 0; i < N; i++) {
      B.Add((i * K) % N);
    }
 
    HashSet<int> C = new HashSet<int>();
 
    // Print Answer
    if (IsPossible(A, B, C, N)) {
      Console.WriteLine("YES");
    }
    else {
      Console.WriteLine("NO");
    }
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    int[] arr = { 1, 2, 0 };
    int K = 5;
    int N = arr.Length;
 
    RearrangeArray(arr, N, K);
  }
}
 
// This code is contributed by phasing17




<script>
 
// JavaScript program for the above approach
 
// Function to check if it is possible
// to generate all numbers in range
// [0, N-1] using the sum of elements
// + in the multiset A and B mod N
function isPossible(A, B, C, N){
 
    // If no more pair of elements
    // can be selected
    if(A.length == 0 || B.length == 0){
     
        // If the number of elements
        // in C = N, then return true
        if(C.size == N)
            return true
         
        // Otherwise return false
        else
            return false
    }
         
    // Stores the value of final answer
    let ans = false
    for(let x of A){
     
        // Iterate through all the pairs in
        // the given multiset A and B
        for(let y of B){
         
        // Stores the set A without x
            let _A = []
            _A = A
            _A = _A.filter((a)=>a !== x)
             
            // Stores the set A without y
            let _B = B
            _B = _B.filter((a)=>a !== y)
             
            // Stores the set A without x+y%N
            let _C = C
            _C.add((x+y) % N)
             
            // Recursive call
            ans = ans || isPossible(_A, _B, _C, N)
        }
    }
             
    return ans
}
 
// Function to check if it is possible
// to rearrange array elements such that
// (arr[i] + i*K) % N = i
function rearrangeArray(arr, N, K){
 
// Stores the values of arr[] modulo N
    let A = []
    for(let i = 0; i < N; i++)
        A.push(arr[i] % N)
    A.sort()
     
    // Stores all the values of
    // i*K modulo N
    let B = []
    for(let i = 0; i < N; i++)
        B.push((i*K) % N)
    B.sort()
    let C = new Set()
     
    // Print Answer
    if(isPossible(A, B, C, N))
        document.write("YES")
    else
        document.write("NO")
}
 
// Driver code
let arr = [1, 2, 0]
let K = 5
let N = arr.length
rearrangeArray(arr, N, K)
 
// This code is contributed by shinjanpatra
 
</script>

Output: 
YES

 

Time Complexity: O(N*2N)
Auxiliary Space: O(N)


Article Tags :