給定兩個整數 n 和 k,返回范圍 [1, n] 中所有可能的 k 個數的組合。
你可以按 任何順序 返回答案。
使用回溯算法。我們可以按照以下步驟來實現:
- 創建一個輔助函數 backtrack,用來進行回溯搜索。其中包括當前組合的狀態變量 current、起始搜索值 start 和結果集合 result。
- 在回溯函數中,如果當前組合的大小等于 k,則將 current 加入到結果集合中。
- 否則,在 [start, n] 范圍內進行遍歷,選擇一個數加入到當前組合中,并遞歸調用 backtrack 函數搜索下一個數字。
- 搜索完成后,需要回溯,將當前加入的數移除,繼續在下一個位置搜索其他可能的數。
#include <vector>void backtrack(int start, int n, int k, std::vector<int>& current, std::vector<std::vector<int>>& result) {if (current.size() == k) {result.push_back(current);return;}for (int i = start; i <= n; ++i) {current.push_back(i);backtrack(i + 1, n, k, current, result);current.pop_back(); // Backtrack}
}std::vector<std::vector<int>> combine(int n, int k) {std::vector<std::vector<int>> result;std::vector<int> current;backtrack(1, n, k, current, result);return result;
}
時間復雜度分析:
在回溯函數中,進行了一個從 start 到 n 的循環,每個數都嘗試加入到當前組合中,并進行遞歸調用。
對于每個位置,有兩種選擇:選或者不選,因此總共有 2^k 種可能的組合,其中 k 為要選擇的數的個數。
每個組合的生成過程中,需要 O(k) 的時間來復制和移除元素。
因此,總的時間復雜度為 O(2^k * k),其中 k 為要選擇的數的個數。
空間復雜度分析:
在遞歸調用過程中,需要 O(k) 的棧空間來存儲當前的組合情況,其中 k 為要選擇的數的個數。
存儲結果的容器需要額外的 O? 空間來存儲所有可能的組合,其中 C 為所有可能的組合數量。
因此,總的空間復雜度為 O(k + C),其中 k 為要選擇的數的個數,C 為所有可能的組合數量。
綜合來看,給定的組合算法的時間復雜度是指數級別的,取決于要選擇的數的個數和范圍的大小。而空間復雜度則主要受遞歸調用和結果集合的影響。