77. 组合

保持忙碌。                                                 ——《人性的优点》

77. 组合

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

你可以按 任何顺序 返回答案。

示例 1:

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

示例 2:

输入:n = 1, k = 1
输出:[[1]]

提示:

1 <= n <= 20
1 <= k <= n

思路:(回溯)
  • 如果解决一个问题有多个步骤,每一个步骤有多种方法,题目又要我们找出所有的方法,可以使用回溯算法;
  • 回溯算法是在一棵树上的 深度优先遍历(因为要找所有的解,所以需要遍历);
  • 组合问题,相对于排列问题而言,不计较一个组合内元素的顺序性(即 [1, 2, 3] 与 [1, 3, 2] 认为是同一个组合),因此很多时候需要按某种顺序展开搜索,这样才能做到不重不漏。

代码:(Java)

import java.util.ArrayList;
import java.util.List;

public class combine_backtracking {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int n = 4;
		int k = 2;
		System.out.println(combine(n,k));

	}
	public static List<List<Integer>> combine(int n, int k) {
		List<List<Integer>> combinations = new ArrayList<>();
		if(k <= 0 || n < k) {
			return combinations;
		}
		List<Integer> combination = new ArrayList<>();
		boolean [] hasVisited = new boolean[n+1];
		backTracking(combinations, combination, hasVisited, 1, n , k);
		return combinations;
    }
	private static void backTracking(List<List<Integer>> combinations, List<Integer> combination, boolean[] hasVisited,int begin, int n, int k) {
		// TODO 自动生成的方法存根
		if(combination.size() == k) {
			combinations.add(new ArrayList<>(combination));
			return;
		}
		for(int i = begin; i <= n; i++) {
			if(hasVisited[i] == true) {
				continue;
			}
			combination.add(i);
			hasVisited[i] = true;
			backTracking(combinations, combination, hasVisited, i ,n , k);
			combination.remove(combination.size() - 1);
			hasVisited[i] = false;
		}
	}
}
运行结果:

77. 组合_第1张图片

相同解法的题目:

257. 二叉树的所有路径
79. 单词搜索
93. 复原 IP 地址
17. 电话号码的字母组合
46. 全排列
47. 全排列 II

注:仅供学习参考

题目来源:力扣

你可能感兴趣的:(java,LeetCode,算法,leetcode,数据结构)