最小化给定数组中的拆分以找到最多 2 个元素的子集,总和最多为 K
给定一个包含N个整数的数组arr[]和一个整数K ,任务是计算可以划分数组的几乎 2 个元素的最小子集数,使得每个子集中的元素总和几乎为K 。
例子:
Input: arr[] = {1, 2, 3}, K = 3
Output: 2
Explanation: The given array can be divided into subsets as {1, 2} and {3}, and the sum of both the the subsets is atmost K. Hence, the count of subsets is 2 which is the minimum possible.
Input: arr[] = {3, 2, 2, 3, 1}, K = 3
Output: 4
Input: arr[] = {3, 2, 2, 3, 1}, K = 2
Output: -1
方法:在两个指针方法的帮助下,可以使用贪心方法来解决给定的问题。这个想法是将具有最小值的整数与最大可能值组合在一起,以使它们的总和不超过K 。请按照以下步骤解决给定问题:
- 以非递减顺序对给定数组进行排序。
- 创建两个变量i = 0和j = N – 1 ,其中i表示第一个索引, j表示数组的最后一个索引。
- 如果arr[i]和arr[j]之和几乎为K ,则增加 i 并减少 j。此外,将子集计数增加1 。
- 如果arr[i]和arr[j]之和大于K ,则减少j并增加子集计数。
下面是上述方法的实现:
C++14
// C++ program of the above approach
#include
using namespace std;
// Function to split array into minimum
// subsets of at most 2 elements with
// sum of each subset at most K
int minSubsetCnt(vector& arr, int K)
{
// Sort arr in increasing order
sort(arr.begin(), arr.end());
// If it is impossible
if (arr[arr.size() - 1] > K) {
return -1;
}
// Stores the count of subsets
int cnt = 0;
// Starting pointer
int i = 0;
// End pointer
int j = arr.size() - 1;
// Loop for the two
// pointer approach
while (i <= j) {
if (arr[i] + arr[j] <= K) {
cnt++;
i++;
j--;
}
else {
cnt++;
j--;
}
}
// Return Answer
return cnt;
}
// Driver Code
int main()
{
vector arr{ 3, 2, 2, 3, 1 };
int K = 3;
cout << minSubsetCnt(arr, K);
return 0;
}
Java
// Java program of the above approach
import java.util.*;
class GFG{
// Function to split array into minimum
// subsets of at most 2 elements with
// sum of each subset at most K
static int minSubsetCnt(int[] arr, int K)
{
// Sort arr in increasing order
Arrays.sort(arr);
// If it is impossible
if (arr[arr.length - 1] > K)
{
return -1;
}
// Stores the count of subsets
int cnt = 0;
// Starting pointer
int i = 0;
// End pointer
int j = arr.length - 1;
// Loop for the two
// pointer approach
while (i <= j)
{
if (arr[i] + arr[j] <= K)
{
cnt++;
i++;
j--;
}
else
{
cnt++;
j--;
}
}
// Return Answer
return cnt;
}
// Driver Code
public static void main(String args[])
{
int[] arr = { 3, 2, 2, 3, 1 };
int K = 3;
System.out.print(minSubsetCnt(arr, K));
}
}
// This code is contributed by sanjoy_62
Python
# Python program of the above approach
# Function to split array into minimum
# subsets of at most 2 elements with
# sum of each subset at most K
def minSubsetCnt(arr, K):
# Sort arr in increasing order
arr.sort()
# If it is impossible
if (arr[len(arr) - 1] > K):
return -1
# Stores the count of subsets
cnt = 0;
# Starting pointer
i = 0;
# End pointer
j = len(arr) - 1;
# Loop for the two
# pointer approach
while (i <= j):
if (arr[i] + arr[j] <= K):
cnt = cnt + 1
i = i + 1
j = j - 1
else:
cnt = cnt + 1
j = j - 1
# Return Answer
return cnt
# Driver Code
arr = [ 3, 2, 2, 3, 1 ]
K = 3
print(minSubsetCnt(arr, K))
# This code is contributed by Samim Hossain Mondal.
C#
// C# implementation for the above approach
using System;
class GFG
{
// Function to split array into minimum
// subsets of at most 2 elements with
// sum of each subset at most K
static int minSubsetCnt(int[] arr, int K)
{
// Sort arr in increasing order
Array.Sort(arr);
// If it is impossible
if (arr[arr.Length - 1] > K)
{
return -1;
}
// Stores the count of subsets
int cnt = 0;
// Starting pointer
int i = 0;
// End pointer
int j = arr.Length - 1;
// Loop for the two
// pointer approach
while (i <= j)
{
if (arr[i] + arr[j] <= K)
{
cnt++;
i++;
j--;
}
else
{
cnt++;
j--;
}
}
// Return Answer
return cnt;
}
// Driver Code
public static void Main()
{
int[] arr = { 3, 2, 2, 3, 1 };
int K = 3;
Console.Write(minSubsetCnt(arr, K));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
4
时间复杂度: O(N*log N)
辅助空间: O(1)