classSolution{ List<List<Integer>> ans = new ArrayList<List<Integer>>();
public List<List<Integer>> combine(int n, int k) { dfs(1, n, k, new ArrayList<Integer>()); return ans; }
//在[start, end] 选取 k 个数 privatevoiddfs(int start, int end, int k, List<Integer> cur){ // k == 0 直接返回 if(k == 0){ ans.add(new ArrayList<Integer>(cur)); return; } //对每一个数进行枚举 for(int i = 0; start + i <= end; i++){ cur.add(start + i); //继续在[start + i + 1, end] 范围内选取 k - 1 个数 dfs(start + i + 1, end, k - 1, cur); //删除当前选取的数,重新循环 cur.remove(cur.size() - 1); } } }
同时我们注意到,使用ArrayList 进行删除效率很低,将其改为 ArrayDeque。在进行循环的时候,我们选取的退出条件为start + i <= end,其实还可以缩小一点,当[start + i, end] 中的元素小于 k 个时,我们可以直接退出,将该条件修改为start + i <= end - k + 1。
//当[start + i, end]范围内数字个数小于 k 个时退出循环 for(int i = 0; start + i <= end - k + 1; i++){ path.addLast(start + i); dfs(start + i + 1, end, k - 1, path); path.removeLast(); } } }