Count of ways to split a given number
Last Updated :
01 May, 2024
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));
}
}
Python
# 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();
Time Complexity: O(2^n)
Auxiliary Space: O(n)
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;
}
Java
import java.util.*;
public class Main {
// Recursive function to find the number of ways to
// split a number
static int findWays(int remainingSum, int currentNumber,
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
static int solve(int n)
{
if (n <= 0)
return 0;
int[][] dp = new int[n + 1][n + 1];
for (int[] row : dp) {
Arrays.fill(row, -1);
}
return findWays(n, 1, dp);
}
public static void main(String[] args)
{
// Function call
System.out.println(solve(5));
}
}
// This code is contributed by shivamgupta310570
Python
# Recursive function to find the number of ways to
# split a number
def findWays(remainingSum, currentNumber, dp):
if remainingSum == 0:
return 1
if remainingSum < 0 or currentNumber > remainingSum:
return 0
if dp[remainingSum][currentNumber] != -1:
return dp[remainingSum][currentNumber]
# Skip the current number
ways1 = findWays(remainingSum, currentNumber + 1, dp)
# Choose the current number
ways2 = findWays(remainingSum - currentNumber, currentNumber, dp)
dp[remainingSum][currentNumber] = ways1 + ways2
return dp[remainingSum][currentNumber]
# Function to find the number of ways to split a number
def solve(n):
if n <= 0:
return 0
dp = [[-1] * (n + 1) for _ in range(n + 1)]
return findWays(n, 1, dp)
# Example usage
print(solve(5))
JavaScript
// Recursive function to find the number of ways to split a number
function findWays(remainingSum, currentNumber, 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
let ways1 = findWays(remainingSum, currentNumber + 1, dp);
// Choose the current number
let ways2 = findWays(remainingSum - currentNumber, currentNumber, dp);
return dp[remainingSum][currentNumber] = ways1 + ways2;
}
// Function to find the number of ways to split a number
function solve(n) {
if (n <= 0)
return 0;
let dp = Array.from({ length: n + 1 }, () => Array(n + 1).fill(-1));
return findWays(n, 1, dp);
}
// Main function
function main() {
// Function call
console.log(solve(5));
}
// Execute the main function
main();
Time Complexity: O(n^2)
Auxiliary Space: O(n)
Share your thoughts in the comments
Please Login to comment...