C++ 0077.cpp
class Solution {
public:
vector<vector<int>> combine(int n, int k) {
// n-k zeros and k ones
vector<int> p(n-k, 0);
for (int i = 0; i < k; i++)
p.push_back(1);
vector<vector<int>> result;
result.reserve(10000);
vector<int> add;
do
{
add.clear();
for (int i = 0; i < p.size(); i++)
if (p[i] == 1)
add.push_back(i+1);
result.push_back(add);
} while (next_permutation(p.begin(), p.end()));
return result;
}
};
Difficulty
and has an acceptance rate of about 75% (1+ million submissions).
Typical patterns to solve this problem:
- Backtracking
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided implementation generates all possible combinations of k distinct numbers chosen from the range 1 to n. It does so by constructing a binary mask that represents the selection of elements, then iterating through every lexicographic permutation of that mask. For each permutation, the positions of the set bits are translated into the actual numbers of the combination, which are collected into the final result vector.
Initialization
The algorithm begins by creating a vector p that holds n-k zeros followed by k ones. This binary representation encodes the initial combination where the smallest k numbers are selected.
vector<int> p(n-k, 0);
for (int i = 0; i < k; i++)
p.push_back(1);
The result container is pre-allocated with a reserve of 10000 elements, which reduces the number of dynamic allocations when the number of combinations is moderate.
vector<vector<int>> result;
result.reserve(10000);
An auxiliary vector add is declared to temporarily hold the numbers belonging to the current combination.
Combination Generation
Inside the do-while loop, the algorithm clears the temporary vector add at the start of each iteration. It then scans the mask p and records the indices of all entries equal to 1. Because the mask is zero-based while the required numbers are one-based, each recorded index is incremented by one.
add.clear();
for (int i = 0; i < p.size(); i++)
if (p[i] == 1)
add.push_back(i + 1);
The populated add vector now represents one concrete combination, which is appended to the result collection.
result.push_back(add);
Permutation Loop
The core of the enumeration relies on std::next_permutation, which rearranges the mask p into its next lexicographic ordering. The loop continues until all distinct permutations have been visited, guaranteeing that every possible placement of the k ones among the n positions is examined.
} while (next_permutation(p.begin(), p.end()));
Because the initial mask places all zeros before the ones, the first call to next_permutation produces the smallest lexicographic arrangement that contains a 1 at the earliest possible position, and the final arrangement consists of all ones followed by zeros, completing the enumeration.
Result Construction
After the permutation loop terminates, the function returns the fully populated result vector, which contains each combination as a separate inner vector of integers.
return result;
Edge Cases
The algorithm naturally handles the situation where k equals 0. In that case, the mask p consists solely of zeros, the inner loop never pushes any index into add, and a single empty combination is added to result. Conversely, when k equals n, the mask is composed entirely of ones; the inner loop records every index from 1 to n, producing a single combination that contains the full range. The use of next_permutation on a uniformly valued mask (all zeros or all ones) results in a single iteration, correctly reflecting the combinatorial extremes.
Performance Optimizations
Pre-allocating storage for result with reserve(10000) reduces the overhead of repeated memory allocations as combinations are appended. The temporary vector add is reused across iterations; it is cleared rather than re-created, which avoids unnecessary construction and destruction of internal storage. The mask p is a compact representation that leverages the highly optimized next_permutation algorithm from the standard library, providing an efficient means to traverse the combinatorial space without explicit recursion or backtracking. By translating mask positions to actual numbers only after each permutation, the code minimizes work per iteration to a simple linear scan of length n.
ELI5 - Simplified Explanation
Imagine you have a row of special blocks. Some blocks are colored with a zero and some are colored with a one. The number of blocks with a zero is decided by taking n and subtracting k, and the rest of the blocks have a one.
The code starts by putting all these blocks into a long line. It looks at the line to find which positions have a one. If a position has a one, the code remembers the number of that position by adding one to it and puts that number into a small basket. Once it finds all the ones, it places that basket into a bigger toy box that holds all the different combinations.
After finishing one line, the code shuffles the blocks into a brand new order. It uses a clever trick to make sure every single possible way of arranging those zeros and ones is tried exactly once. It keeps doing this over and over again, making new baskets and adding them to the toy box until there are no more ways to rearrange the blocks. When every single arrangement has been checked, the toy box is filled with all the different groups of numbers.
Code Quality
Complexity Analysis
As a rule of thumb, the maximum input size for one second execution time is
- factorial: up to 10 elements
- exponential: up to 20 elements
- polynomial: a few thousand elements
- loglinear: up to 100,000 elements
- linear: a few million elements
- logarithmic: a billion elements
- constant: practically unlimited
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| author | solutions | |||||||||||
| www | AlgoMonster | C++ | Python | Java | TS | |||||||
| WalkCCC | C++ | Python | Java | |||||||||
| leetcode.ca | C++ | Python | Java | Rust | C# | Go | TS | |||||
| LeetcodeHelp | C++ | Python | Java | |||||||||
| MemoryLimitExceeded | C++ | Python | ||||||||||
| Progiez | C++ | Python | Java | |||||||||
| github | aylei | Rust | ||||||||||
| begeekmyfriend | C | |||||||||||
| BigEggStudy | C# | |||||||||||
| black-shadows | C++ | |||||||||||
| chandansgowda | Python | |||||||||||
| charles-wangkai | Java | |||||||||||
| chenyanzhe | C++ | |||||||||||
| everthis | JS | |||||||||||
| fpdjsns | C++ | |||||||||||
| gaosq0604 | Python | |||||||||||
| gouthampradhan | Java | |||||||||||
| halfrost | Go | |||||||||||
| haoel | C++ | |||||||||||
| JoshCrozier | JS | |||||||||||
| keineahnung2345 | C++ | |||||||||||
| lennylxx | C++ | |||||||||||
| linouk23 | C++ | |||||||||||
| lkwq007 | Python | |||||||||||
| luangong | C++ | |||||||||||
| MacJim | C++ | |||||||||||
| martianoff | Scala | |||||||||||
| qiyuangong | Python | |||||||||||
| ruoru | Rust | |||||||||||
| suxrobGM | C# | |||||||||||
| varunu28 | Java | |||||||||||
| vli02 | C | |||||||||||
| vthwang | Java | |||||||||||
| wisdompeak | C++ | |||||||||||
| XiaotaoGuo | C++ | |||||||||||
| yuanliu666 | Kotlin | |||||||||||
| zfang399 | C++ | |||||||||||
| AlgoMonster | C++, Python, Java, TypeScript | |||||||||||
| WalkCCC | C++, Python, Java | |||||||||||
| leetcode.ca | C++, C#, Go, Java, Python, Rust, TypeScript | |||||||||||
| LeetcodeHelp | C++, Java, Python | |||||||||||
| MemoryLimitExceeded | Python, C++ | |||||||||||
| Progiez | C++, Java, Python | |||||||||||
| aylei | Rust | |||||||||||
| begeekmyfriend | C | |||||||||||
| BigEggStudy | C# | |||||||||||
| black-shadows | C++, C++ | |||||||||||
| chandansgowda | Python | |||||||||||
| charles-wangkai | Java | |||||||||||
| chenyanzhe | C++ | |||||||||||
| everthis | JavaScript | |||||||||||
| fpdjsns | C++ | |||||||||||
| gaosq0604 | Python | |||||||||||
| gouthampradhan | Java | |||||||||||
| halfrost | Go | |||||||||||
| haoel | C++ | |||||||||||
| JoshCrozier | JavaScript | |||||||||||
| keineahnung2345 | C++ | |||||||||||
| lennylxx | C++ | |||||||||||
| linouk23 | C++ | |||||||||||
| lkwq007 | Python | |||||||||||
| luangong | C++ | |||||||||||
| MacJim | C++ | |||||||||||
| martianoff | Scala | |||||||||||
| qiyuangong | Python | |||||||||||
| ruoru | Rust | |||||||||||
| suxrobGM | C# | |||||||||||
| varunu28 | Java | |||||||||||
| vli02 | C | |||||||||||
| vthwang | Java | |||||||||||
| wisdompeak | C++ | |||||||||||
| XiaotaoGuo | C++ | |||||||||||
| yuanliu666 | Kotlin | |||||||||||
| zfang399 | C++ |
Videos
Similar Problems
- problem 46: Permutations
Solved On The Same Day
- problem 1: Two Sum
- problem 9: Palindrome Number
- problem 14: Longest Common Prefix
- problem 20: Valid Parentheses
- problem 26: Remove Duplicates from Sorted Array
- problem 27: Remove Element
- problem 83: Remove Duplicates from Sorted List
- problem 88: Merge Sorted Array
- problem 94: Binary Tree Inorder Traversal
- problem 100: Same Tree
- problem 104: Maximum Depth of Binary Tree
- problem 121: Best Time to Buy and Sell Stock
- problem 136: Single Number
- problem 141: Linked List Cycle
- problem 169: Majority Element
- problem 190: Reverse Bits
- problem 226: Invert Binary Tree
- problem 234: Palindrome Linked List
- problem 1114: Print in Order
- problem 3: Longest Substring Without Repeating Characters
- problem 7: Reverse Integer
- problem 8: String to Integer (atoi)
- problem 11: Container With Most Water
- problem 12: Integer to Roman
- problem 15: 3Sum
- problem 17: Letter Combinations of a Phone Number
- problem 22: Generate Parentheses
- problem 31: Next Permutation
- problem 36: Valid Sudoku
- problem 39: Combination Sum
- problem 40: Combination Sum II
- problem 45: Jump Game II
- problem 46: Permutations
- problem 47: Permutations II
- problem 48: Rotate Image
- problem 49: Group Anagrams
- problem 55: Jump Game
- problem 59: Spiral Matrix II
- problem 75: Sort Colors
- problem 91: Decode Ways
- problem 95: Unique Binary Search Trees II
- problem 96: Unique Binary Search Trees
- problem 134: Gas Station
- problem 164: Maximum Gap
- problem 189: Rotate Array
- problem 215: Kth Largest Element in an Array
- problem 238: Product of Array Except Self
- problem 287: Find the Duplicate Number
- problem 322: Coin Change
- problem 347: Top K Frequent Elements
- problem 377: Combination Sum IV
- problem 438: Find All Anagrams in a String
- problem 474: Ones and Zeroes
- problem 518: Coin Change II
- problem 526: Beautiful Arrangement
- problem 763: Partition Labels
- problem 983: Minimum Cost For Tickets
- problem 994: Rotting Oranges
- problem 1027: Longest Arithmetic Subsequence
- problem 2140: Solving Questions With Brainpower
- problem 2466: Count Ways To Build Good Strings
- problem 4: Median of Two Sorted Arrays
- problem 41: First Missing Positive
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality