题目地址
https://leetcode.com/problems/permutations/description/
题目描述
Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路
这道题目是求集合,并不是求极值
,因此动态规划不是特别切合,因此我们需要考虑别的方法。
这种题目其实有一个通用的解法,就是回溯法。
网上也有大神给出了这种回溯法解题的
通用写法,这里的所有的解法使用通用方法解答。
除了这道题目还有很多其他题目可以用这种通用解法,具体的题目见后方相关题目部分。
我们先来看下通用解法的解题思路,我画了一张图:
通用写法的具体代码见下方代码区。
关键点解析
- 回溯法
- backtrack 解题公式
代码
- 语言支持: Javascript, Python3
Javascript Code:
/* * @lc app=leetcode id=46 lang=javascript * * [46] Permutations * * https://leetcode.com/problems/permutations/description/ * * algorithms * Medium (53.60%) * Total Accepted: 344.6K * Total Submissions: 642.9K * Testcase Example: '[1,2,3]' * * Given a collection of distinct integers, return all possible permutations. * * Example: * * * Input: [1,2,3] * Output: * [ * [1,2,3], * [1,3,2], * [2,1,3], * [2,3,1], * [3,1,2], * [3,2,1] * ] * * */ function backtrack(list, tempList, nums) { if (tempList.length === nums.length) return list.push([...tempList]); for(let i = 0; i < nums.length; i++) { if (tempList.includes(nums[i])) continue; tempList.push(nums[i]); backtrack(list, tempList, nums); tempList.pop(); } } /** * @param {number[]} nums * @return {number[][]} */ var permute = function(nums) { const list = []; backtrack(list, [], nums) return list };
Python3 Code:
class Solution: def permute(self, nums: List[int]) -> List[List[int]]: """itertools库内置了这个函数""" return itertools.permutations(nums) def permute2(self, nums: List[int]) -> List[List[int]]: """自己写回溯法""" res = [] def _backtrace(nums, pre_list): if len(nums) <= 0: res.append(pre_list) else: for i in nums: # 注意copy一份新的调用,否则无法正常循环 p_list = pre_list.copy() p_list.append(i) left_nums = nums.copy() left_nums.remove(i) _backtrace(left_nums, p_list) _backtrace(nums, []) return res
Python Code:
class Solution: def permute(self, nums: List[int]) -> List[List[int]]: """itertools库内置了这个函数""" import itertools return itertools.permutations(nums) def permute2(self, nums: List[int]) -> List[List[int]]: """自己写回溯法""" res = [] def _backtrace(nums, pre_list): if len(nums) <= 0: res.append(pre_list) else: for i in nums: # 注意copy一份新的调用,否则无法正常循环 p_list = pre_list.copy() p_list.append(i) left_nums = nums.copy() left_nums.remove(i) _backtrace(left_nums, p_list) _backtrace(nums, []) return res def permute3(self, nums: List[int]) -> List[List[int]]: """回溯的另一种写法""" res = [] length = len(nums) def _backtrack(start=0): if start == length: # nums[:] 返回 nums 的一个副本,指向新的引用,这样后续的操作不会影响已经已知解 res.append(nums[:]) for i in range(start, length): nums[start], nums[i] = nums[i], nums[start] _backtrack(start+1) nums[start], nums[i] = nums[i], nums[start] _backtrack() return res
相关题目
- 31.next-permutation
- 39.combination-sum
- 40.combination-sum-ii
- 47.permutations-ii
- 60.permutation-sequence(TODO)
- 78.subsets
- 90.subsets-ii
- 113.path-sum-ii
- 131.palindrome-partitioning
可以是三进制么?二进制有什么好处?题解:为什么叫电子计算机?算盘应该没有二进制
LeetCode题解645. 错误的集合集合 S 包含从1到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复。给定一个数组 nums 代表了集合 S 发生错误后的结果。你的任务是首先寻找到重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。示例 1:输入: nums = [1,2,2,4]输出: [2,…
LeetCode题解深度优先遍历和回溯的关系?深度优先遍历的范围更大还是回溯的范围更大?为什么?题解:我的理解是:dfs是回溯思想的一种体现- 回溯:是在整个搜索空间中搜索出可行解,在搜索过程中不断剪枝回退,这是回溯的思想,这个搜索空间并没有限制于特定的数据结构。- dfs:dfs是指特定的数据结构中如图,树(特殊的图)中搜索答案,范围限制在了特定的数据结构。个人拙见。
LeetCode题解盲人买袜子。他们都各自买了两对黑袜和两对白袜,八对袜子的布质、大小完全相同,而每对袜子都有一张商标纸连着。两位盲人不小心将八对袜子混在一起。他们每人怎样才能取回黑袜和白袜各两对呢?题解:暴力破解, 把袜子都拆开 一人一只 哈哈
LeetCode题解白石搭白塔输入黑块和白块的数量,用输入的方块数目建塔,输出最大高度和种数,两种方法至少一层颜色不同才能算不同的方法塔满足下列要求:1. 塔底层块数和高度数值相同,逐层递减1,最高层为12. 每层颜色相同