1. Binary Pick / Don't Pick Full Range Traversal
Intuition
Define solve(currNum, current). Base case: if current.length == k, add copy to result. If currNum > n, terminate. Recurse by either picking currNum or skipping currNum.
When to apply: Simple conceptual baseline.
Algorithm
- If
current.length == k, addcurrenttoresultand return. - If
currNum > n, return. - Pick branch:
current.push(currNum),solve(currNum + 1),current.pop(). - Don't pick branch:
solve(currNum + 1).
#include <iostream>#include <vector> using namespace std; class Solution { void solve(int num, int n, int k, vector<int>& current, vector<vector<int>>& result) { if (current.size() == k) { result.push_back(current); return; } if (num > n) return; // Pick num current.push_back(num); solve(num + 1, n, k, current, result); current.pop_back(); // Don't pick num solve(num + 1, n, k, current, result); } public: vector<vector<int>> combine(int n, int k) { vector<vector<int>> result; vector<int> current; solve(1, n, k, current, result); return result; }}; int main() { Solution sol; auto res = sol.combine(4, 2); for (const auto& c : res) { cout << "[ "; for (int v : c) cout << v << " "; cout << "] "; } cout << endl; return 0;}Time & Space Complexity
- Time complexity:
O(2^n * k)— Generates up to 2n binary decisions across all numbers 1..n. - Space complexity:
O(n)— Call stack reaches maximum depth n.