给定一个由N 个整数组成的数组arr[] ,任务是检查是否可以将整数分成两个相等长度的子集,以便任何数组元素的所有重复都属于同一个子集。如果发现是真的,打印“是” 。否则,打印“否” 。
例子:
Input: arr[] = {2, 1, 2, 3}
Output: Yes
Explanation:
One possible way of dividing the array is {1, 3} and {2, 2}
Input: arr[] = {1, 1, 1, 1}
Output: No
朴素方法:解决问题的最简单方法是尝试将数组拆分为两个相等子集的所有可能组合。对于每个组合,检查每个重复是否只属于两个集合中的一个。如果发现是真的,则打印“是” 。否则,打印“否” 。
时间复杂度: O(2 N ),其中 N 是给定整数的大小。
辅助空间: O(N)
有效的方法:可以通过将给定数组的所有元素的频率存储在数组freq[] 中来优化上述方法。要将元素分成两个相等的集合,每个集合中必须存在N/2 个元素。 因此,要将给定的数组arr[]分成2 个相等的部分, freq[]中必须有一些整数的子集,其总和为N/2 。请按照以下步骤解决问题:
- 将每个元素的频率存储在 Map M 中。
- 现在,创建一个辅助数组aux[]并将其插入其中,所有频率都存储在Map 中。
- 给定的问题简化为在数组aux[] 中找到具有给定总和N/2的子集。
- 如果上述步骤中存在任何这样的子集,则打印“是” 。否则,打印“否” 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to create the frequency
// array of the given array arr[]
vector findSubsets(vector arr, int N)
{
// Hashmap to store the
// frequencies
map M;
// Store freq for each element
for (int i = 0; i < N; i++)
{
M[arr[i]]++;
}
// Get the total frequencies
vector subsets;
int I = 0;
// Store frequencies in
// subset[] array
for(auto playerEntry = M.begin(); playerEntry != M.end(); playerEntry++)
{
subsets.push_back(playerEntry->second);
I++;
}
// Return frequency array
return subsets;
}
// Function to check is sum
// N/2 can be formed using
// some subset
bool subsetSum(vector subsets, int N, int target)
{
// dp[i][j] store the answer to
// form sum j using 1st i elements
bool dp[N + 1][target + 1];
// Initialize dp[][] with true
for (int i = 0; i < N + 1; i++)
dp[i][0] = true;
// Fill the subset table in the
// bottom up manner
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= target; j++)
{
dp[i][j] = dp[i - 1][j];
// If curren element is
// less than j
if (j >= subsets[i - 1])
{
// Update current state
dp[i][j] |= dp[i - 1][j - subsets[i - 1]];
}
}
}
// Return the result
return dp[N][target];
}
// Function to check if the given
// array can be split into required sets
void divideInto2Subset(vector arr, int N)
{
// Store frequencies of arr[]
vector subsets = findSubsets(arr, N);
// If size of arr[] is odd then
// print "Yes"
if ((N) % 2 == 1)
{
cout << "No" << endl;
return;
}
int subsets_size = subsets.size();
// Check if answer is true or not
bool isPossible = subsetSum(subsets, subsets_size, N / 2);
// Print the result
if (isPossible)
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
}
int main()
{
// Given array arr[]
vector arr{2, 1, 2, 3};
int N = arr.size();
// Function Call
divideInto2Subset(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to create the frequency
// array of the given array arr[]
private static int[] findSubsets(int[] arr)
{
// Hashmap to store the frequencies
HashMap M
= new HashMap<>();
// Store freq for each element
for (int i = 0; i < arr.length; i++) {
M.put(arr[i],
M.getOrDefault(arr[i], 0) + 1);
}
// Get the total frequencies
int[] subsets = new int[M.size()];
int i = 0;
// Store frequencies in subset[] array
for (
Map.Entry playerEntry :
M.entrySet()) {
subsets[i++]
= playerEntry.getValue();
}
// Return frequency array
return subsets;
}
// Function to check is sum N/2 can be
// formed using some subset
private static boolean
subsetSum(int[] subsets,
int target)
{
// dp[i][j] store the answer to
// form sum j using 1st i elements
boolean[][] dp
= new boolean[subsets.length
+ 1][target + 1];
// Initialize dp[][] with true
for (int i = 0; i < dp.length; i++)
dp[i][0] = true;
// Fill the subset table in the
// bottom up manner
for (int i = 1;
i <= subsets.length; i++) {
for (int j = 1;
j <= target; j++) {
dp[i][j] = dp[i - 1][j];
// If curren element is
// less than j
if (j >= subsets[i - 1]) {
// Update current state
dp[i][j]
|= dp[i - 1][j
- subsets[i - 1]];
}
}
}
// Return the result
return dp[subsets.length][target];
}
// Function to check if the given
// array can be split into required sets
public static void
divideInto2Subset(int[] arr)
{
// Store frequencies of arr[]
int[] subsets = findSubsets(arr);
// If size of arr[] is odd then
// print "Yes"
if ((arr.length) % 2 == 1) {
System.out.println("No");
return;
}
// Check if answer is true or not
boolean isPossible
= subsetSum(subsets,
arr.length / 2);
// Print the result
if (isPossible) {
System.out.println("Yes");
}
else {
System.out.println("No");
}
}
// Driver Code
public static void main(String[] args)
{
// Given array arr[]
int[] arr = { 2, 1, 2, 3 };
// Function Call
divideInto2Subset(arr);
}
}
// This code is contributed by divyesh072019
Python3
# Python3 program for the
# above approach
from collections import defaultdict
# Function to create the
# frequency array of the
# given array arr[]
def findSubsets(arr):
# Hashmap to store
# the frequencies
M = defaultdict (int)
# Store freq for each element
for i in range (len(arr)):
M[arr[i]] += 1
# Get the total frequencies
subsets = [0] * len(M)
i = 0
# Store frequencies in
# subset[] array
for j in M:
subsets[i] = M[j]
i += 1
# Return frequency array
return subsets
# Function to check is
# sum N/2 can be formed
# using some subset
def subsetSum(subsets, target):
# dp[i][j] store the answer to
# form sum j using 1st i elements
dp = [[0 for x in range(target + 1)]
for y in range(len(subsets) + 1)]
# Initialize dp[][] with true
for i in range(len(dp)):
dp[i][0] = True
# Fill the subset table in the
# bottom up manner
for i in range(1, len(subsets) + 1):
for j in range(1, target + 1):
dp[i][j] = dp[i - 1][j]
# If current element is
# less than j
if (j >= subsets[i - 1]):
# Update current state
dp[i][j] |= (dp[i - 1][j -
subsets[i - 1]])
# Return the result
return dp[len(subsets)][target]
# Function to check if the given
# array can be split into required sets
def divideInto2Subset(arr):
# Store frequencies of arr[]
subsets = findSubsets(arr)
# If size of arr[] is odd then
# print "Yes"
if (len(arr) % 2 == 1):
print("No")
return
# Check if answer is true or not
isPossible = subsetSum(subsets,
len(arr) // 2)
# Print the result
if (isPossible):
print("Yes")
else :
print("No")
# Driver Code
if __name__ == "__main__":
# Given array arr
arr = [2, 1, 2, 3]
# Function Call
divideInto2Subset(arr)
# This code is contributed by Chitranayal
C#
// C# program for the above
// approach
using System;
using System.Collections.Generic;
class GFG{
// Function to create the frequency
// array of the given array arr[]
static int[] findSubsets(int[] arr)
{
// Hashmap to store the
// frequencies
Dictionary M =
new Dictionary();
// Store freq for each element
for (int i = 0; i < arr.Length; i++)
{
if(M.ContainsKey(arr[i]))
{
M[arr[i]]++;
}
else
{
M[arr[i]] = 1;
}
}
// Get the total frequencies
int[] subsets = new int[M.Count];
int I = 0;
// Store frequencies in
// subset[] array
foreach(KeyValuePair
playerEntry in M)
{
subsets[I] = playerEntry.Value;
I++;
}
// Return frequency array
return subsets;
}
// Function to check is sum
// N/2 can be formed using
// some subset
static bool subsetSum(int[] subsets,
int target)
{
// dp[i][j] store the answer to
// form sum j using 1st i elements
bool[,] dp = new bool[subsets.Length + 1,
target + 1];
// Initialize dp[][] with true
for (int i = 0;
i < dp.GetLength(0); i++)
dp[i, 0] = true;
// Fill the subset table in the
// bottom up manner
for (int i = 1;
i <= subsets.Length; i++)
{
for (int j = 1; j <= target; j++)
{
dp[i, j] = dp[i - 1, j];
// If curren element is
// less than j
if (j >= subsets[i - 1])
{
// Update current state
dp[i, j] |= dp[i - 1,
j - subsets[i - 1]];
}
}
}
// Return the result
return dp[subsets.Length,
target];
}
// Function to check if the given
// array can be split into required sets
static void divideInto2Subset(int[] arr)
{
// Store frequencies of arr[]
int[] subsets = findSubsets(arr);
// If size of arr[] is odd then
// print "Yes"
if ((arr.Length) % 2 == 1)
{
Console.WriteLine("No");
return;
}
// Check if answer is true or not
bool isPossible = subsetSum(subsets,
arr.Length / 2);
// Print the result
if (isPossible)
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
}
// Driver code
static void Main()
{
// Given array arr[]
int[] arr = {2, 1, 2, 3};
// Function Call
divideInto2Subset(arr);
}
}
// This code is contributed by divyeshrabadiya07
Javascript
输出:
Yes
时间复杂度: O(N*M),其中 N 是数组的大小,M 是给定数组中不同元素的总数。
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。