📌  相关文章
📜  检查数组是否可以分为总和可被 k 整除的对

📅  最后修改于: 2021-10-27 08:28:05             🧑  作者: Mango

给定一个整数数组和一个数字 k,编写一个函数,如果给定的数组可以分成对,使得每对的和都可以被 k 整除,则该函数返回 true。

例子:

一个简单的解决方案是遍历每个元素 arr[i]。查找是否还有另一个尚未访问的元素具有像(k – arr[i]%k)这样的余数。如果没有这样的元素,则返回 false。如果找到一对,则将两个元素都标记为已访问。此解决方案的时间复杂度为 O(n 2) ,并且需要 O(n) 额外空间。

一个有效的解决方案是使用哈希。

1) If length of given array is odd, return false. 
    An odd length array cannot be divided into pairs.
2) Traverse input array and count occurrences of 
    all remainders (use (arr[i] % k)+k)%k for handling the case of negative integers as well). 
      freq[((arr[i] % k)+k)%k]++
3) Traverse input array again. 
   a) Find the remainder of the current element.
   b) If remainder divides k into two halves, then
      there must be even occurrences of it as it 
      forms pair with itself only.
   c) If the remainder is 0, then there must be 
      even occurrences.
   c) Else, number of occurrences of current 
      the remainder must be equal to a number of 
      occurrences of "k - current remainder".

一种有效的方法是使用散列(C++ 中的 unordered_map 和Java的HashMap )。

下图是上述方法的试运行:

下面是上述方法的实现:

C++
// A C++ program to check if arr[0..n-1] can be divided
// in pairs such that every pair is divisible by k.
#include 
using namespace std;
 
// Returns true if arr[0..n-1] can be divided into pairs
// with sum divisible by k.
bool canPairs(int arr[], int n, int k)
{
    // An odd length array cannot be divided into pairs
    if (n & 1)
        return false;
 
    // Create a frequency array to count occurrences
    // of all remainders when divided by k.
    unordered_map freq;
 
    // Count occurrences of all remainders
    for (int i = 0; i < n; i++)
        freq[((arr[i] % k) + k) % k]++;
 
    // Traverse input array and use freq[] to decide
    // if given array can be divided in pairs
    for (int i = 0; i < n; i++) {
        // Remainder of current element
        int rem = ((arr[i] % k) + k) % k;
 
        // If remainder with current element divides
        // k into two halves.
        if (2 * rem == k) {
            // Then there must be even occurrences of
            // such remainder
            if (freq[rem] % 2 != 0)
                return false;
        }
 
        // If remainder is 0, then there must be two
        // elements with 0 remainder
        else if (rem == 0) {
            if (freq[rem] & 1)
                return false;
        }
 
        // Else number of occurrences of remainder
        // must be equal to number of occurrences of
        // k - remainder
        else if (freq[rem] != freq[k - rem])
            return false;
    }
    return true;
}
 
// Driver code
int main()
{
    int arr[] = { 92, 75, 65, 48, 45, 35 };
    int k = 10;
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    canPairs(arr, n, k) ? cout << "True" : cout << "False";
    return 0;
}


Java
// JAVA program to check if arr[0..n-1] can be divided
// in pairs such that every pair is divisible by k.
import java.util.HashMap;
public class Divisiblepair {
    // Returns true if arr[0..n-1] can be divided into pairs
    // with sum divisible by k.
    static boolean canPairs(int ar[], int k)
    {
        // An odd length array cannot be divided into pairs
        if (ar.length % 2 == 1)
            return false;
 
        // Create a frequency array to count occurrences
        // of all remainders when divided by k.
        HashMap hm = new HashMap<>();
 
        // Count occurrences of all remainders
        for (int i = 0; i < ar.length; i++) {
            int rem = ((ar[i] % k) + k) % k;
            if (!hm.containsKey(rem)) {
                hm.put(rem, 0);
            }
            hm.put(rem, hm.get(rem) + 1);
        }
 
        // Traverse input array and use freq[] to decide
        // if given array can be divided in pairs
        for (int i = 0; i < ar.length; i++) {
            // Remainder of current element
            int rem = ((ar[i] % k) + k) % k;
 
            // If remainder with current element divides
            // k into two halves.
            if (2 * rem == k) {
                // Then there must be even occurrences of
                // such remainder
                if (hm.get(rem) % 2 == 1)
                    return false;
            }
 
            // If remainder is 0, then there must be two
            // elements with 0 remainder
            else if (rem == 0) {
                // Then there must be even occurrences of
                // such remainder
                if (hm.get(rem) % 2 == 1)
                    return false;
            }
 
            // Else number of occurrences of remainder
            // must be equal to number of occurrences of
            // k - remainder
            else {
                if (hm.get(k - rem) != hm.get(rem))
                    return false;
            }
        }
        return true;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 92, 75, 65, 48, 45, 35 };
        int k = 10;
 
        // Function call
        boolean ans = canPairs(arr, k);
        if (ans)
            System.out.println("True");
        else
            System.out.println("False");
    }
}
 
// This code is contributed by Rishabh Mahrsee


Python3
# Python3 program to check if
# arr[0..n-1] can be divided
# in pairs such that every
# pair is divisible by k.
from collections import defaultdict
 
# Returns true if arr[0..n-1] can be
# divided into pairs with sum
# divisible by k.
 
 
def canPairs(arr, n, k):
 
    # An odd length array cannot
    # be divided into pairs
    if (n & 1):
        return 0
 
    # Create a frequency array to
    # count occurrences of all
    # remainders when divided by k.
    freq = defaultdict(lambda: 0)
 
    # Count occurrences of all remainders
    for i in range(0, n):
        freq[((arr[i] % k) + k) % k] += 1
 
    # Traverse input array and use
    # freq[] to decide if given array
    # can be divided in pairs
    for i in range(0, n):
 
        # Remainder of current element
        rem = ((arr[i] % k) + k) % k
 
        # If remainder with current element
        # divides k into two halves.
        if (2 * rem == k):
 
            # Then there must be even occurrences
            # of such remainder
            if (freq[rem] % 2 != 0):
                return 0
 
        # If remainder is 0, then there
        # must be two elements with 0 remainde
        elif (rem == 0):
            if (freq[rem] & 1):
                return 0
 
            # Else number of occurrences of
            # remainder must be equal to
            # number of occurrences of
            # k - remainder
        elif (freq[rem] != freq[k - rem]):
             return 0
 
    return 1
 
 
# Driver code
arr = [92, 75, 65, 48, 45, 35]
k = 10
n = len(arr)
 
# Function call
if (canPairs(arr, n, k)):
    print("True")
else:
    print("False")
 
# This code is contributed by Stream_Cipher


C#
// C# program to check if arr[0..n-1]
// can be divided in pairs such that
// every pair is divisible by k.
using System.Collections.Generic;
using System;
 
class GFG {
 
    // Returns true if arr[0..n-1] can be
    // divided into pairs with sum
    // divisible by k.
    static bool canPairs(int[] ar, int k)
    {
 
        // An odd length array cannot
        // be divided into pairs
        if (ar.Length % 2 == 1)
            return false;
 
        // Create a frequency array to count
        // occurrences of all remainders when
        // divided by k.
        Dictionary hm
            = new Dictionary();
 
        // Count occurrences of all remainders
        for (int i = 0; i < ar.Length; i++) {
            int rem = ((ar[i] % k) + k) % k;
            if (!hm.ContainsKey(rem)) {
                hm[rem] = 0;
            }
            hm[rem]++;
        }
 
        // Traverse input array and use freq[]
        // to decide if given array can be
        // divided in pairs
        for (int i = 0; i < ar.Length; i++) {
 
            // Remainder of current element
            int rem = ((ar[i] % k) + k) % k;
 
            // If remainder with current element
            // divides k into two halves.
            if (2 * rem == k) {
 
                // Then there must be even occurrences
                // of such remainder
                if (hm[rem] % 2 == 1)
                    return false;
            }
 
            // If remainder is 0, then there
            // must be two elements with 0
            // remainder
            else if (rem == 0) {
                // Then there must be even occurrences
                // of such remainder
                if (hm[rem] % 2 == 1)
                    return false;
            }
 
            // Else number of occurrences of remainder
            // must be equal to number of occurrences of
            // k - remainder
            else {
                if (hm[k - rem] != hm[rem])
                    return false;
            }
        }
        return true;
    }
 
    // Driver code
    public static void Main()
    {
        int[] arr = { 92, 75, 65, 48, 45, 35 };
        int k = 10;
 
        // Function call
        bool ans = canPairs(arr, k);
        if (ans)
            Console.WriteLine("True");
        else
            Console.WriteLine("False");
    }
}
 
// This code is contributed by Stream_Cipher


Javascript


输出
True

时间复杂度: O(n)。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程