持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情🚀🚀
491. 递增子序列 - 力扣(LeetCode)
const findSubsequences = (nums) => {
const res = [];
const len = nums.length;
const set = new Set();
const dfs = (start, path) => {
if (path.length >= 2) {
const str = path.toString(); // path数组 转成字符串
if (!set.has(str)) { // set中没有存有当前path
res.push(path.slice()); // 推入一份path的拷贝
set.add(str); // 存入set,记录一下
}
}
for (let i = start; i < len; i++) { // 枚举出当前所有的选项,从start到末尾
const prev = path[path.length - 1]; // 上一个选择,即path数组的末尾元素
const cur = nums[i]; // 当前选择
if (path.length == 0 || prev <= cur) { // 如果path为空,或满足递增关系,则可选择
path.push(cur); // 选择当前的数字
dfs(i + 1, path); // 继续往下递归,注意传的是i+1
path.pop(); // 撤销选择当前数字,选择别的数字
}
}
};
dfs(0, []); //递归的入口,从下标0到末尾的数组中选择合适的数加入path,组成解集。初始path是空数组
return res;
};
难点
这题最大的难点是去重
有没有发现如果这里还是用了我们之前的去重逻辑,会对原数组进行一个排序,但排序之后又会发现我们改变了原数组,这直接把题意都改了,这样还要别人来找递增子序列??
所以这道题要寻找一个全新的去重逻辑
- 用set去重
const str = path.toString(); // path数组 转成字符串 if (!set.has(str)) { // set中没有存有当前path res.push(path.slice()); // 推入一份path的拷贝 set.add(str); // 存入set,记录一下 }
注意要放字符串~
- path入栈
注意条件是要符合递增才能入栈
46. 全排列 - 力扣(LeetCode)
var permute = function(nums) {
const res = [], path = [];
let used = []
let len = nums.length;
backtracking();
return res;
function backtracking() {
if(path.length === len) {
res.push([...path]);
return;
}
for (let i = 0; i < len; i++ ) {
if(used[i]) continue;
path.push(nums[i]);
used[i] = true; // 同支
backtracking();
path.pop();
used[i] = false;
}
}
};
来到全排列了~
难点
dfs
里没有index
了,因为每次都要重新遍历一次- 要用
used
数组记录,防止重复遍历。 - 出栈的时候也别忘了
used
数组
47. 全排列 II - 力扣(LeetCode)
var permuteUnique = function (nums) {
nums.sort((a, b) => {
return a - b
})
let result = []
let path = []
function backtracing(used) {
if (path.length === nums.length) {
result.push([...path])
return
}
for (let i = 0; i < nums.length; i++) {
if (nums[i] === nums[i - 1] && !used[i - 1]) {
continue
}
if (!used[i]) {
used[i] = true;
path.push(nums[i])
backtracing(used)
path.pop()
used[i] = false
}
}
}
backtracing([])
return result
};
难点
这里在used的基础上进行了去重
if (nums[i] === nums[i - 1] && !used[i - 1]) {
continue
}
核心是这句话
!used[i - 1]
如果不加这句话,[1,1,2]
,这样直接会在第二层遍历1
的时候就会出问题。