Open In App

Count of ways to split a given number

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:

Below is the implementation of the algorithm:

#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;
}
# 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()
// 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:

#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)

Article Tags :