Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情
一、题目描述:
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
示例 1:
输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]
示例 2:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
二、思路与实现:
思路一:
与上一篇不一样的是,本篇全排列带重复数字。但仍然适用回溯法;
- 基本回溯思路;
- 每次向某一路径后面添加新元素的时候,用一个set记录已加入的元素列表,如果判断之前已经加入过,则跳过当前元素。
代码实现:
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.slice())
return
}
for (let i = 0; i < nums.length; i++) {
if (i > 0 && 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
};
思路二:
循环的时候,加一个对象缓存一下,下次再遇到这个数,开头的结果就直接略过了;
var permuteUnique = function (nums) {
if (nums.length === 1) {
return [nums];
}
let res = [], map = {};
nums.forEach((e, index) => {
if (!map[e]) {
map[e] = 1;
let arr = [...nums];
arr.splice(index, 1);
permuteUnique(arr).forEach((e1) => {
let arr = [e, ...e1];
res.push(arr);
});
}
});
return res;
};
三、总结:
这道题目和前一篇的区别在与:给定一个可包含重复数字的序列,要返回:所有不重复的全排列。
即:去重。抓住此点就行啦~~