Split numbers from 1 to N into two equal sum subsets

Given an integer N, the task is to divide the numbers from 1 to N into two nonempty subsets such that the sum of elements in the set is equal. Print the element in the subset. If we can’t form any subset then print -1.

Examples:

Input N = 4 
Output: 
Size of subset 1 is: 2 
Elements of the subset are: 1 4 
Size of subset 2 is: 2 
Elements of the subset are: 2 3 
Explanation: 
The first and the second set have equal sum that is 5.

Input: N = 8 
Output: 
Size of subset 1 is: 4 
Elements of the subset are: 1 8 3 6 
Size of subset 2 is: 4 
Elements of the subset are: 2 7 4 5 
Explanation: 
The first and the second set have equal sum that is 18.

 

Approach: To solve the problem mentioned above we have to observe the two cases for integer N, which is even and odd. Below are the observations:



  1. When N is even: For this case, we can choose the numbers in pair and assign to each of the sets alternatively.
    For Example, N = 8 so the numbers are 1, 2, 3, 4, 5, 6, 7, 8, and 1, 3, 6, 8 can be grouped together in a set.
    This is because we can take two numbers between 1 and N at once and assign them to same sets, now if in first turn we take 1 and N and assign it to first set then if we increase the first number i.e 1 by one and decrease the second number i.e N by one the total sum remains same (1 + N = 2 + N – 1) and we assign 2 and N-1 to second set, therefore in this order we can divide the numbers into pairs alternatively to each set. Here N = 2 is an exception.
     
  2. When N is odd: For this case, then the sum of each subset is half of the sum of the first N natural number. Iterate through the numbers from N to 1 if the number is less than or equal to the required sum then we include this number otherwise if the number is greater than the required sum then we ignore the number and include the number which is equal to the required sum. Also, keep track of the numbers used for one set so that we can find the numbers for another subset.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to print the two set
void findAns(int N)
{
    // Base case
    if (N <= 2) {
        cout << "-1";
        return;
    }
  
    // Sum of first numbers upto N
    int value = (N * (N + 1)) / 2;
  
    // To store the first set
    vector<int> v1;
  
    // To store the second set
    vector<int> v2;
  
    // When N is even
    if (!(N & 1)) {
  
        int turn = 1;
        int start = 1;
        int last = N;
        while (start < last) {
  
            if (turn) {
                v1.push_back(start);
                v1.push_back(last);
                turn = 0;
            }
            else {
                v2.push_back(start);
                v2.push_back(last);
                turn = 1;
            }
  
            // Increment start
            start++;
  
            // Decrement last
            last--;
        }
    }
  
    // When N is odd
    else {
  
        // Required sum of the subset
        int rem = value / 2;
  
        // Boolean array to keep
        // track of used elements
        bool vis[N + 1];
  
        for (int i = 1; i <= N; i++)
            vis[i] = false;
  
        vis[0] = true;
  
        // Iterate from N to 1
        for (int i = N; i >= 1; i--) {
            if (rem > i) {
                v1.push_back(i);
                vis[i] = true;
                rem -= i;
            }
  
            else {
                v1.push_back(rem);
                vis[rem] = true;
                break;
            }
        }
  
        // Assigning the unused
        // elements to second subset
        for (int i = 1; i <= N; i++) {
            if (!vis[i])
                v2.push_back(i);
        }
    }
  
    // Print the elements of first set
    cout << "Size of subset 1 is: ";
    cout << v1.size() << "\n";
    cout << "Elements of the subset are: ";
    for (auto c : v1)
        cout << c << " ";
  
    cout << endl;
  
    // Print the elements of second set
    cout << "Size of subset 2 is: ";
    cout << v2.size() << "\n";
    cout << "Elements of the subset are: ";
    for (auto c : v2)
        cout << c << " ";
}
  
// Driver Code
int main()
{
    // Given Number
    int N = 8;
  
    // Function Call
    findAns(N);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach 
import java.util.*;
   
class GFG{
      
// Function to print the two set 
public static void findAns(int N) 
    // Base case 
    if (N <= 2
    
        System.out.print("-1");
        return
    
  
    // Sum of first numbers upto N 
    int value = (N * (N + 1)) / 2
  
    // To store the first set 
    Vector<Integer> v1 = new Vector<Integer>(); 
  
    // To store the second set 
    Vector<Integer> v2 = new Vector<Integer>();
  
    // When N is even 
    if ((N & 1) == 0)
    
        int turn = 1
        int start = 1
        int last = N; 
        while (start < last) 
        
            if (turn == 1)
            
                v1.add(start); 
                v1.add(last); 
                turn = 0
            
            else 
            
                v2.add(start); 
                v2.add(last);
                turn = 1
            
  
            // Increment start 
            start++; 
  
            // Decrement last 
            last--; 
        
    
  
    // When N is odd 
    else
    
          
        // Required sum of the subset 
        int rem = value / 2
  
        // Boolean array to keep 
        // track of used elements 
        boolean[] vis = new boolean[N + 1]; 
  
        for(int i = 1; i <= N; i++) 
            vis[i] = false
  
        vis[0] = true
  
        // Iterate from N to 1 
        for(int i = N; i >= 1; i--)
        
            if (rem > i)
            
                v1.add(i); 
                vis[i] = true
                rem -= i; 
            
            else
            
                v1.add(rem); 
                vis[rem] = true
                break
            
        
  
        // Assigning the unused 
        // elements to second subset 
        for(int i = 1; i <= N; i++)
        
            if (!vis[i]) 
                v2.add(i); 
        
    
  
    // Print the elements of first set 
    System.out.print("Size of subset 1 is: ");
    System.out.println(v1.size());
    System.out.print("Elements of the subset are: ");
      
    for(Integer c : v1)     
        System.out.print(c + " ");
          
    System.out.println();
  
    // Print the elements of second set 
    System.out.print("Size of subset 2 is: ");
    System.out.println(v2.size());
    System.out.print("Elements of the subset are: ");
      
    for(Integer c : v2)     
        System.out.print(c + " ");
  
// Driver code
public static void main(String[] args) 
{
      
    // Given Number 
    int N = 8
  
    // Function Call 
    findAns(N); 
}
}
  
// This code is contributed by divyeshrabadiya07

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach 
using System;
using System.Collections.Generic;
  
class GFG{
      
// Function to print the two set 
public static void findAns(int N) 
      
    // Base case 
    if (N <= 2) 
    
        Console.Write("-1");
        return
    
  
    // Sum of first numbers upto N 
    int value = (N * (N + 1)) / 2; 
  
    // To store the first set 
    List<int> v1 = new List<int>(); 
  
    // To store the second set 
    List<int> v2 = new List<int>();
  
    // When N is even 
    if ((N & 1) == 0)
    
        int turn = 1; 
        int start = 1; 
        int last = N; 
          
        while (start < last) 
        
            if (turn == 1)
            
                v1.Add(start); 
                v1.Add(last); 
                turn = 0; 
            
            else
            
                v2.Add(start); 
                v2.Add(last);
                turn = 1; 
            
  
            // Increment start 
            start++; 
  
            // Decrement last 
            last--; 
        
    
  
    // When N is odd 
    else
    
          
        // Required sum of the subset 
        int rem = value / 2; 
  
        // Boolean array to keep 
        // track of used elements 
        bool[] vis = new bool[N + 1]; 
  
        for(int i = 1; i <= N; i++) 
            vis[i] = false
  
        vis[0] = true
  
        // Iterate from N to 1 
        for(int i = N; i >= 1; i--)
        
            if (rem > i)
            
                v1.Add(i); 
                vis[i] = true
                rem -= i; 
            
            else
            
                v1.Add(rem); 
                vis[rem] = true
                break
            
        
  
        // Assigning the unused 
        // elements to second subset 
        for(int i = 1; i <= N; i++)
        
            if (!vis[i]) 
                v2.Add(i); 
        
    
  
    // Print the elements of first set 
    Console.Write("Size of subset 1 is: ");
    Console.WriteLine(v1.Count);
    Console.Write("Elements of the subset are: ");
      
    foreach(int c in v1)     
        Console.Write(c + " ");
          
    Console.WriteLine();
  
    // Print the elements of second set 
    Console.Write("Size of subset 2 is: ");
    Console.WriteLine(v2.Count);
    Console.Write("Elements of the subset are: ");
      
    foreach(int c in v2)     
        Console.Write(c + " ");
  
// Driver code
public static void Main(String[] args) 
{
      
    // Given number 
    int N = 8; 
  
    // Function call 
    findAns(N); 
}
}
  
// This code is contributed by Amit Katiyar

chevron_right


Output: 

Size of subset 1 is: 4
Elements of the subset are: 1 8 3 6 
Size of subset 2 is: 4
Elements of the subset are: 2 7 4 5

Time Complexity: O(N) 
Auxiliary Space: O(N)
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.