代码随想录算法训练营第二十二天 | 回溯

33 阅读2分钟

LeetCode 77 组合

📖 考察点

回溯

📖 题意理解

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

💡 解题思路

组合问题 回溯

🔑 关键点总结

剪枝 如果剩余的值已经不够组成k个值,直接跳过

💻 代码实现

JavaScript

var combine = function (n, k) {
	let res = [];
	let path = [];
	const backtracking = (start) => {
		if (path.length === k) {
			res.push([...path]);
			return;
		}
		for (let i = start; i <= n - (k - path.length) + 1; i++) {
			path.push(i);
			backtracking(i + 1, res);
			path.pop();
		}
	};
	backtracking(1, res);
	return res;
};

⏱️ 复杂度分析

📚 总结与反思


LeetCode 216.组合总和III

📖 考察点

回溯

📖 题意理解

找出所有相加之和为 n **的 k ****个数的组合,且满足下列条件:

  • 只使用数字1到9
  • 每个数字 最多使用一次 

返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

💡 解题思路

JavaScript

var combinationSum3 = function (k, n) {
	let sum = 0;
	let path = [];
	let res = [];
	let suffixSum = Array.from(
		{
			length: 9,
		},
		(_, index) => {
			return index + 1;
		}
	);
	// 后缀和
	for (let i = suffixSum.length - 2; i >= 0; i--) {
		suffixSum[i] += suffixSum[i + 1];
	}
	// 后缀和要找对, 不是suffix[i] 而是suffix[i-1]
	const backtracking = (start) => {
		if (sum === n && path.length === k) {
			res.push([...path]);
		}
		if (sum > n) {
			return;
		}
		if (start === 9) {
			1 + 1;
		}
		for (let i = start; i <= 9 - (k - path.length) + 1 && suffixSum[i - 1] >= n - sum; i++) {
			path.push(i);
			sum += i;
			backtracking(i + 1);
			sum -= i;
			path.pop();
		}
	};
	backtracking(1);
	return res;
};

LeetCode 17.电话号码的字母组合

📖 考察点

回溯

📖 题意理解

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

💡 解题思路

JavaScript

var letterCombinations = function (digits) {
	if (!digits) {
		return [];
	}
	let dict = [
		["a", "b", "c"],
		["d", "e", "f"],
		["g", "h", "i"],
		["j", "k", "l"],
		["m", "n", "o"],
		["p", "q", "r", "s"],
		["t", "u", "v"],
		["w", "x", "y", "z"],
	];
	let res = [];
	let path = [];
	const backtracking = (start) => {
		if (path.length === digits.length) {
			res.push(path.join(""));
		}
		if (start >= digits.length) return;
		let curDict = dict[digits[start] - 2];
		for (let i = 0; i < curDict.length; i++) {
			path.push(curDict[i]);
			backtracking(start + 1);
			path.pop();
		}
	};
	backtracking(0);
	return res;
};