[回溯法] -- 77 组合题解 - Java + Python

127 阅读1分钟

给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

做过了前面关于全排列和组合总和的问题,这道题相比而言就更简单了。对应的回溯法的三大要素:

  • 选择列表:当前已经选择的数字
  • 可选择列表:当前位置之后的数组元素列表
  • 终止条件:当前选择列表的长度等于给定的k

选择的过程中也不需要额外的剪枝操作,只需要按照一般回溯法的思路解题即可。

Java解题代码:

class Solution {
    public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> results = new LinkedList<>();
        LinkedList<Integer> track = new LinkedList<>();

        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = i + 1;
        }
        
        dfs(nums, track, results, k, 0);
        results.forEach(System.out :: println);
        return results;
    }
    
    private void dfs(int[] nums, LinkedList<Integer> track, List<List<Integer>> results, int k, int start) {
        if (track.size() == k){
            results.add(new LinkedList<>(track));
            return;
        }

        for(int i = start; i < nums.length; i++){
            track.add(nums[i]);
            dfs(nums, track, results, k, i + 1);
            track.removeLast();
        }
    }
}

Python解题代码:

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        if n == 0 or k > n: return []

        nums = [i for i in range(1, n + 1)]
        results = []

        def dfs(track, nums, k):
            if len(track) == k:
                results.append(track.copy())
                return
            
            for i in range(len(nums)):            
                track.append(nums[i])
                dfs(track, nums[i + 1 : ], k)
                track.pop()

        
        dfs([], nums, k)
        return results