Open In App

Count of ways to split a given number

Last Updated : 18 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given a number N, the task is to find the count of unique ways to split it into different parts.

Note: {2, 1} and {1, 2} will be considered as one way.

Examples:

Input: n = 5
Output: 7
Explanation: There are 7 ways to split 5:
5
4 + 1
3 + 2
3 + 1 + 1
2 + 2 + 1
2 + 1 + 1 + 1
1 + 1 + 1 + 1 + 1

Input: n = 3
Output: 3
Explanation: There are 3 ways to split 3:
3
2 + 1
1 + 1 + 1

Count of ways to split a given number using Recursion:

Recurrence Relation:

findWays(remainingSum, currentNumber) = findWays(remainingSum – currentNumber, currentNumber) + findWays(remainingSum, currentNumber + 1)

Approach: To solve the problem follow the below idea:

To count all the ways to split a given number remainingSum into smaller numbers, then for each smaller number currentNumber we have two choices:

  • Split remainingSum by subtracting currentNumber: Subtract the current number X from N and call the findWays function recursively with the updated remainingSum and the same currentNumber i.e., findWays(remainingSum – currentNumber, currentNumber)
  • Exclude the currentNumber: Call the findWays function recursively with the same remainingSum and the greater currentNumber. i.e., findWays(remainingSum, currentNumber + 1).

Step-by-step algorithm:

  • Maintain a recursive function, say findWays(remainingSum, currentNumber) to find the number of ways to split remainingSum into parts of size >= currentNumber.
  • In each recursuve call, there are two choices:
    • Do not break the remainingSum in a part of size = currentNumber and choose to break in a bigger part by calling findWays(remainingSum, currentNumber + 1)
    • Break the remainingSum in a part of size = currentNumber and again call findWays(remainingSum – currentNumber, currentNumber)
  • If at any recursive call, the remainingSum becomes negative then it means that the number cannot split any further, so return 0.
  • If at any recursive call, the remainingSum becomes 0, then it means that the number has already been split, so return 1.
  • After all the recursive calls, return the final answer.

Below is the implementation of the algorithm:

C++
#include <iostream>
using namespace std;

// recursive function to find the number of ways to split a
// number
int findWays(int remainingSum, int currentNumber)
{
    if (remainingSum == 0)
        return 1;
    if (remainingSum < 0 || currentNumber > remainingSum)
        return 0;
    // Skip the current number
    int ways1 = findWays(remainingSum, currentNumber + 1);
    // Choose the current number
    int ways2 = findWays(remainingSum - currentNumber,
                         currentNumber);
    return ways1 + ways2;
}

// function to find the number of ways to split a number
int solve(int n)
{
    if (n <= 0)
        return 0;
    return findWays(n, 1);
}

int main()
{
      // function call
      int n = 5;
    cout << solve(n) << "\n";
    return 0;
}
Java
import java.util.Scanner;

public class Main {
    // Recursive function to find the number of ways to split a number
    static int findWays(int remainingSum, int currentNumber) {
        if (remainingSum == 0)
            return 1;
        if (remainingSum < 0 || currentNumber > remainingSum)
            return 0;
        // Skip the current number
        int ways1 = findWays(remainingSum, currentNumber + 1);
        // Choose the current number
        int ways2 = findWays(remainingSum - currentNumber, currentNumber);
        return ways1 + ways2;
    }

    // Function to find the number of ways to split a number
    static int solve(int n) {
        if (n <= 0)
            return 0;
        return findWays(n, 1);
    }

    public static void main(String[] args) {
        // Input number
        int n = 5;
        // Function call and output result
        System.out.println(solve(n));
    }
}
Python3
# Recursive function to find the number of ways to split a number
def find_ways(remaining_sum, current_number):
    if remaining_sum == 0:
        return 1
    if remaining_sum < 0 or current_number > remaining_sum:
        return 0
    # Skip the current number
    ways1 = find_ways(remaining_sum, current_number + 1)
    # Choose the current number
    ways2 = find_ways(remaining_sum - current_number, current_number)
    return ways1 + ways2

# Function to find the number of ways to split a number
def solve(n):
    if n <= 0:
        return 0
    return find_ways(n, 1)

# Main function
def main():
    n = 5  # Define the input value
    # Function call and output
    print(solve(n))

# Call the main function to execute the program
main()
JavaScript
// Recursive function to find the number of ways to split a number
function findWays(remainingSum, currentNumber) {
    if (remainingSum === 0)
        return 1;
    if (remainingSum < 0 || currentNumber > remainingSum)
        return 0;
    // Skip the current number
    const ways1 = findWays(remainingSum, currentNumber + 1);
    // Choose the current number
    const ways2 = findWays(remainingSum - currentNumber, currentNumber);
    return ways1 + ways2;
}

// Function to find the number of ways to split a number
function solve(n) {
    if (n <= 0)
        return 0;
    return findWays(n, 1);
}

// Main function
function main() {
    const n = 5; // Define the input value
    // Function call and output
    console.log(solve(n));
}

// Call the main function to execute the program
main();

Output
7

Time Complexity: O(2^n)
Auxiliary Space: O(n)

Count of ways to split a given number using Dynamic Programming (Memoization):

Algorithm: To solve the problem, follow the below idea:

We can observe that the above recursive approach has Overlapping Subproblems and Optimal Substructure so we can optimize it by storing the already computed results using Memoization. So, now we can use a dp[][] array of size N X N, such that dp[i][j] stores the number of ways to split number i into parts such that each part >= j.

Below is the implementation of the algorithm:

C++
#include <bits/stdc++.h>
using namespace std;

// recursive function to find the number of ways to split a
// number
int findWays(int remainingSum, int currentNumber, vector<vector<int>> &dp)
{
    if (remainingSum == 0)
        return 1;
    if (remainingSum < 0 || currentNumber > remainingSum)
        return 0;
      if(dp[remainingSum][currentNumber] != -1)
      return dp[remainingSum][currentNumber];
    // Skip the current number
    int ways1 = findWays(remainingSum, currentNumber + 1, dp);
    // Choose the current number
    int ways2 = findWays(remainingSum - currentNumber,
                         currentNumber, dp);
    return dp[remainingSum][currentNumber] = ways1 + ways2;
}

// function to find the number of ways to split a number
int solve(int n)
{
    if (n <= 0)
        return 0;
      vector<vector<int>> dp(n + 1, vector<int>(n + 1, -1));
    return findWays(n, 1, dp);
}

int main()
{
      // function call
    cout << solve(5) << "\n";
    return 0;
}

Output
7

Time Complexity: O(n^2)
Auxiliary Space: O(n)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads