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]

Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • The fact that each array element arr[i] is updated as (arr[i] + i*K) % N. So, the value arr[i] % N and i*K % N can be calculated independently.
  • If a multiset A contains all the values of arr[i] % N and multiset B contains all the values of i*K % N for all values of i in the range [0, N-1],  generate all possible combinations of elements in A and B and store (A[i] + B[i]) % N in a set. If the size of the resulting set is N, it is possible to rearrange the array in the required way.

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

  • Create a multiset A containing all the values of arr[i] % N for all values of i in the range [0, N-1].
  • Similarly, create a multiset B contains all the values of i*K % N for all values of i in the range [0, N-1].
  • Create a recursive function to iterate over all pairs of integers in A and B, add their sum modulo N in set C and recursively call for the remaining elements.
  • If at any point, the size of the set C = N, return true else return false.

Below is the implementation of the above approach:

C++




// 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;
}


Java




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




# 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


C#




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


Javascript




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



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