Check whether N items can be divided into K groups of unique size
Last Updated :
18 Sep, 2023
Given integers N and K, the task is to check if it is possible to divide N numbers into K groups such that all the K groups are of different size and each part has at least one number.
Examples:
Input: N = 5, K = 2
Output: Yes
Explanation: 5 numbers can be divided into 2 parts of different size. The possible size of the groups can be (1, 4) and (2, 3).
Input: N = 3, K = 3
Output: No
Explanation: 3 numbers cannot be divide into 3 groups of unique size.
Approach:
- Define a function canPartition that takes four arguments: N (the total number of items to be partitioned), K (the number of groups to partition into), curr (the current item being considered for partitioning), and num_groups (the current number of groups formed so far).
- The base case for the recursive function is when N is 0 and num_groups is equal to K. This means that a valid partition has been found and the function should return true.
- Another base case is when N is negative, curr is greater than N, or num_groups is greater than or equal to K. This means that the current partition is invalid and the function should return false.
- Iterate over the range from curr to N (inclusive) and for each value i, recursively call canPartition with N-i as the new N value, K as the same, i+1 as the new curr value, and num_groups+1 as the new num_groups value.
- If the recursive call returns true, this means that a valid partition has been found and the function should return true.
- If all possible partitions have been checked and none of them are valid, the function should backtrack and try a different group size by returning false.
C++
#include <bits/stdc++.h>
using namespace std;
bool canPartition( int N, int K, int curr, int num_groups) {
if (N == 0 && num_groups == K) {
return true ;
}
if (N < 0 || curr > N || num_groups >= K) {
return false ;
}
for ( int i = curr; i <= N; i++) {
if (canPartition(N-i, K, i+1, num_groups+1)) {
return true ;
}
}
return false ;
}
int main() {
int N = 6, K = 5;
if (canPartition(N, K, 1, 0)) {
cout << "Yes" ;
} else {
cout << "No" ;
}
return 0;
}
|
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
int N = 6 , K = 5 ;
if (canPartition(N, K, 1 , 0 )) {
System.out.println( "Yes" );
} else {
System.out.println( "No" );
}
}
public static boolean canPartition( int N, int K, int curr, int num_groups) {
if (N == 0 && num_groups == K) {
return true ;
}
if (N < 0 || curr > N || num_groups >= K) {
return false ;
}
for ( int i = curr; i <= N; i++) {
if (canPartition(N - i, K, i + 1 , num_groups + 1 )) {
return true ;
}
}
return false ;
}
}
|
Python
def can_partition(N, K, curr, num_groups):
if N = = 0 and num_groups = = K:
return True
if N < 0 or curr > N or num_groups > = K:
return False
for i in range (curr, N + 1 ):
if can_partition(N - i, K, i + 1 , num_groups + 1 ):
return True
return False
if __name__ = = '__main__' :
N = 6
K = 5
if can_partition(N, K, 1 , 0 ):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
class GFG
{
static bool CanPartition( int N, int K, int curr, int numGroups)
{
if (N == 0 && numGroups == K)
{
return true ;
}
if (N < 0 || curr > N || numGroups >= K)
{
return false ;
}
for ( int i = curr; i <= N; i++)
{
if (CanPartition(N - i, K, i + 1, numGroups + 1))
{
return true ;
}
}
return false ;
}
static void Main()
{
int N = 6, K = 5;
if (CanPartition(N, K, 1, 0))
{
Console.WriteLine( "Yes" );
}
else
{
Console.WriteLine( "No" );
}
}
}
|
Javascript
function canPartition(N, K, curr, num_groups) {
if (N === 0 && num_groups === K) {
return true ;
}
if (N < 0 || curr > N || num_groups >= K) {
return false ;
}
for (let i = curr; i <= N; i++) {
if (canPartition(N - i, K, i + 1, num_groups + 1)) {
return true ;
}
}
return false ;
}
const N = 6;
const K = 5;
if (canPartition(N, K, 1, 0)) {
console.log( "Yes" );
} else {
console.log( "No" );
}
|
Time Complexity: O(2^N), where N is the input integer N. This is because the algorithm tries all possible combinations of partitions, and there can be up to 2^N different combinations.
Space Complexity: O(K), where K is the number of groups. This is because at any point during the recursion, there will be at most K recursive calls on the call stack, corresponding to the K groups being formed. Each call takes up constant space, so the overall space complexity is O(K).
Approach: The problem can be solved on the basis of following observation.
To divide N numbers into K groups such that each group has at least one number and no two groups have same size:
- There should be at least K numbers. If N < K, then division is not possible.
- If N > K then the K groups will be at least of size 1, 2, 3, 4 . . . K . So N must be at least K*(K + 1)/2.
Therefore, the condition to be satisfied is N ≥ K*(K + 1)/2.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
void checkPartition( int N, int K)
{
if (N < (K * (K + 1)) / 2) {
cout << "No" ;
}
else {
cout << "Yes" ;
}
}
int main()
{
int N = 6, K = 5;
checkPartition(N, K);
return 0;
}
|
C
#include <stdio.h>
void checkPartition( int N, int K)
{
if (N < (K * (K + 1)) / 2) {
printf ( "No" );
}
else {
printf ( "Yes" );
}
}
int main()
{
int N = 6, K = 5;
checkPartition(N, K);
return 0;
}
|
Java
import java.io.*;
class GFG {
public static void checkPartition( int N, int K)
{
if (N < (K * (K + 1 ) / 2 )) {
System.out.print( "No" );
}
else {
System.out.print( "Yes" );
}
}
public static void main(String[] args)
{
int N = 6 , K = 5 ;
checkPartition(N, K);
}
}
|
Python3
def checkPartition(N, K):
if (N < (K * (K + 1 )) / / 2 ):
print ( "No" )
else :
print ( "Yes" )
if __name__ = = '__main__' :
N = 6
K = 5
checkPartition(N, K)
|
C#
using System;
class GFG {
public static void checkPartition( int N, int K)
{
if (N < (K * (K + 1) / 2)) {
Console.Write( "No" );
}
else {
Console.Write( "Yes" );
}
}
public static void Main()
{
int N = 6, K = 5;
checkPartition(N, K);
}
}
|
Javascript
<script>
function checkPartition(N, K)
{
if (N < Math.floor((K * (K + 1)) / 2)) {
document.write( "No" );
}
else {
document.write( "Yes" );
}
}
let N = 6, K = 5;
checkPartition(N, K);
</script>
|
Time Complexity: O(1)
Auxiliary Space: O(1).
Share your thoughts in the comments
Please Login to comment...