
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
C++ Program to Perform Partition of an Integer in All Possible Ways
In this article, we have a positive integer 'n'. Our task is to generate all possible unique ways to represent 'n' as the sum of positive integers in C++. Each partition should give a sum equal to the given 'n'. Here is an example:
Input: n = 4 Output: 4 3 1 2 2 2 1 1 1 1 1 1
Steps to Perform Unique Partition of Integer
- We start with the current partition i.e. with an initial value of n. Then we print the current partition.
- Then we find the rightmost number that is greater than 1. Then we decrease this value by 1.
- We collect all 1s into the variable rem. After collecting it into rem we divide the rem into smaller parts.
- If the value in the rem is smaller than the current value of n then append it directly and print the partition. If the current value of n is smaller than the rem, then break the rem into smaller parts.
- Repeat the above four steps till all that remains is only 1s.
The following approaches implement the above-mentioned steps to perform a unique partition of integer:
Using Iterative Stack Based Method
In this approach, we have used an array that acts as a stack and a pointer k that always points at the top element. It implements all the steps mentioned above to perform a unique partition of the given integer.
- The first inner while loop (while (k > 0 && a[k] == 1)) finds the rightmost number greater than 1, decreases this number by 1, and collects all 1s into rem.
- The second while loop while (rem > a[k]) breaks the rem into further smaller parts.
Example
Here is the code example, implementing the above-mentioned steps for a unique partition of the integer:
#include <iostream> #include <vector> #include <algorithm> using namespace std; void iterativePartitions(int n) { vector<int> a(n + 1); // To store the partition int k = 1; // Current partition a[1] = n; while (k != 0) { // Print the current partition for (int i = 1; i <= k; i++) { cout << a[i] << " "; } cout << endl; // Create the next partition int rem = 0; // Remaining sum to be partitioned while (k > 0 && a[k] == 1) { rem += a[k--]; // Move back and update rem with ones } if (k == 0) return; a[k]--; rem++; // Breaking the remaining sum into parts while (rem > a[k]) { a[k + 1] = a[k]; rem -= a[k]; k++; } a[k + 1] = rem; k++; } } int main() { int n = 4; cout << "All unique Partitions of " << n << ":" << endl; iterativePartitions(n); return 0; }
The output of the above code is:
All Unique Partitions of 4: 4 3 1 2 2 2 1 1 1 1 1 1
Using Recursive Backtracking
We have used a recursive backtracking approach here for a unique partition of the integer. Using recursion, we find all the possible partitions. We have used backtracking to remove the last added number so that the previous number doesn't get affected.
Example
In this example, we have used the above steps to break the given integer into unique partitions:
#include <iostream> #include <vector> using namespace std; void partitions(int n, vector<int> ¤t, int max_val) { if (n == 0) { for (int x : current) cout << x << " "; cout << endl; return; } for (int i = min(n, max_val); i >= 1; --i) { current.push_back(i); partitions(n - i, current, i); current.pop_back(); } } int main() { int n = 4; vector<int> partition; cout << "All Unique Partitions of " << n << ":\n"; partitions(n, partition, n); return 0; }
The output of the above code is:
All Unique Partitions of 4: 4 3 1 2 2 2 1 1 1 1 1 1
Using In-Place Partitioning
This approach implements the above-mentioned steps using the in-place partitioning method where we have used the iterative approach without creating the extra array. It follows all the above-mentioned steps.
- The while (k >= 0 && p[k] == 1) and if (k < 0) section finds the rightmost value > 1 then decrease it and collect all 1s into the rem_val variable.
- The while (rem_val > p[k]) section breaks the value in rem_val further till we get all 1s.
Example
The following example implements the above steps using in-place partitioning to break the given integers uniquely.
#include <iostream> using namespace std; // Print the current partition void printArr(int p[], int m) { for (int i = 0; i < m; i++) cout << p[i] << " "; cout << endl; } // Print all unique partitions void printAllUniqueParts(int m) { int p[m]; // Store the partition int k = 0; p[k] = m; while (true) { // Print the current partition printArr(p, k + 1); int rem_val = 0; // Find the rightmost number greater than 1 while (k >= 0 && p[k] == 1) { rem_val += p[k]; // Collect all 1s into rem k--; } if (k < 0) return; p[k]--; rem_val++; while (rem_val > p[k]) { p[k + 1] = p[k]; rem_val = rem_val - p[k]; k++; } p[k + 1] = rem_val; k++; } } int main() { cout << "\nAll Unique Partitions of 4:\n"; printAllUniqueParts(4); return 0; }
The output of the above code is:
All Unique Partitions of 4: 4 3 1 2 2 2 1 1 1 1 1 1
Complexity Comparison
Here is a comparison of the time and space complexity of all the above approaches.
Approach | Time Complexity | Space Complexity |
---|---|---|
Iterative Stack | O(2^n) | O(n) |
Recursive Backtracking | O(2^n) | O(n) |
In-Place Partitioning | O(2^n) | O(n) |