📌  相关文章
📜  检查给定数组的元素是否可以重新排列,使得 (arr[i] + i*K) % N = i 对于范围 [0, N-1] 中的所有 i 值

📅  最后修改于: 2022-05-13 01:56:06.213000             🧑  作者: Mango

检查给定数组的元素是否可以重新排列,使得 (arr[i] + i*K) % N = i 对于范围 [0, N-1] 中的所有 i 值

给定一个由N个正整数和一个整数K组成的数组arr[] ,任务是检查数组元素是否可以重新排列,使得(arr[i] + i*K) % N = i对于i的所有值范围[0, N-1]

例子:

朴素方法:给定问题可以通过生成给定数组arr[]的所有可能排列来解决,并检查是否存在满足给定标准的任何此类排列。

时间复杂度: O(N*N!)
辅助空间: O(N)

高效方法:上述方法也可以借助使用递归的 Set 数据结构进行优化。以下是解决给定问题的一些观察结果:

  • 每个数组元素arr[i]更新为(arr[i] + i*K) % N的事实。因此,值arr[i] % Ni*K % N可以独立计算。
  • 如果 multiset A包含arr[i] % N的所有值,multiset B包含[0, N-1]范围内i的所有值的i*K % N的所有值,则生成元素的所有可能组合在AB中并将(A[i] + B[i]) % N存储在一个集合中。如果结果集的大小为N ,则可以以所需的方式重新排列数组。

使用上述观察,可以通过以下步骤解决给定问题:

  • 创建一个多重集A ,其中包含[0, N-1]范围内i的所有值的arr[i] % N的所有值。
  • 类似地,创建一个多重集B包含i*K % N的所有值,用于范围[0, N-1]中的所有i值。
  • 创建一个递归函数来迭代AB中的所有整数对,将它们的和模N添加到集合C中,并递归调用剩余的元素。
  • 如果在任何时候,集合的大小C = N ,则返回true ,否则返回false

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
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 A,
                multiset B,
                set 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 _A = A;
            _A.erase(_A.find(x));
 
            // Stores the set B without y
            multiset _B = B;
            _B.erase(_B.find(y));
 
            // Stores the set C with (x+y)%N
            set _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 A;
    for (int i = 0; i < N; i++) {
        A.insert(arr[i] % N);
    }
 
    // Stores all the values of
    // i*K modulo N
    multiset B;
    for (int i = 0; i < N; i++) {
        B.insert((i * K) % N);
    }
 
    set 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;
}


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


Javascript


输出:
YES

时间复杂度: O(N*2 N )
辅助空间: O(1)