排列
从n个不同元素中,任取m个不同的元素按照一定的顺序排成一列,叫做从n个不同元素中取出m个元素的一个排列. 从n个不同元素中取出m(m≤n)个元素的所有排列的个数,叫做从n个不同元素中取出m个元素的排列数,用符号A(n, m)
表示,此外规定0! = 1
组合
从n个不同元素中,任取m(m≤n)个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合;从n个不同元素中取出m(m≤n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数。用符号C(n,m)
表示C(n,m)=C(n,n-m)
常见的题目
子集
题目来源
思路:
深度: 选择
depth0: [1], []
depth1: [2], []
depth2: [3], []
depth3: back
const subsets = nums => {
const result = []
// 当前路径
const path = []
const dfs = (depth) => {
// 走到第nums.length的时候就不需要往下走了
if (depth === nums.length) {
result.push(path.slice())
return
}
// 采用当前节点值并往下走
path.push(nums[depth])
dfs(depth + 1)
// 不采用当前值并往下走
path.pop()
dfs(depth + 1)
}
dfs(0)
return result
}
全排列
题目来源
思路:
[1, 2, 3] -> [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
深度: 选择:
depth0: [[1], [2], [3]] intersection used[]
depth1: [[1], [2], [3]] intersection used[choice1]
depth2: [[1], [2], [3]] intersection used[choice1, choice2]
depth3: 结束
const permute = nums => {
const used = new Set()
const path = []
const result = []
const dfs = (depth) => {
if (depth === nums.length) {
result.push(path.slice())
return
}
for (let i = 0; i < nums.length; i++) {
if (!used.has(i)) {
used.add(i)
path.push(nums[i])
dfs(depth + 1)
used.delete(i)
path.pop()
}
}
}
dfs(0)
return result
}
括号生成
题目来源
思路:
n = 3 ["((()))","(()())","(())()","()(())","()()()"]
depth0:
=> 左 && (left < n) 或者 右 && (right < left)
depth1:
=> 左 && (left < n) 或者 右 && (right < left)
depth2:
=> 左 && (left < n) 或者 右 && (right < left)
.
.
.
depth2n: 结束
const generateParenthesis = function (n) {
const result = []
const path = []
let left = 0, right = 0
const dfs = depth => {
if (depth === 2 * n) {
result.push(path.slice().join(''))
return
}
if (left < n) {
path.push('(')
left++
dfs(depth + 1)
path.pop()
left--
}
if (right < left) {
right++
path.push(')')
dfs(depth + 1)
path.pop()
right--
}
}
dfs(0)
return result
}
组合总和
题目来源
思路:
candidates = [2,3,6,7], target = 7, result = [[7], [2,2,3]]
candidates = [2,3,5], target = 8, result = [[2,2,2,2],[2,3,3],[3,5]]
depth0: choice in candidates
depth1: choice in candidates
.
.
depth sum > target: back
const combinationSum = (candidates, target) => {
const result = []
const path = []
const dfs = (depth) => {
const cp = path.slice()
const sum = cp.reduce((acc, item) => acc + item, 0)
if (sum === target) {
result.push(cp)
return
}
if (sum > target) {
return
}
for (let i = 0; i < candidates.length; i++) {
path.push(candidates[i])
dfs(depth + 1)
path.pop()
}
}
dfs(0)
const set = new Set()
return result.filter(item => {
let val = item.sort().join("")
if (!set.has(val)) {
set.add(val)
return true
}
return false
})
}
复原IP地址
(https://leetcode-cn.com/probl...
图像渲染
(https://leetcode-cn.com/probl...
单词搜索
(https://leetcode-cn.com/probl...
复原IP地址
(https://leetcode-cn.com/probl...
N皇后
(https://leetcode-cn.com/probl...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。