491.递增子序列
自己的做法:
/**
* @param {number[]} nums
* @return {number[][]}
*/
let road = [];
let path = [];
var findSubsequences = function (nums) {
road = []; //road会有之前的数据,所以需要每次清空road
brektraning(nums, 0);
let obj = {};
road.forEach((val) => {
// 此处不能用 obj.name = '属性值'的方式 因为此处的val是变量,不是固定值
obj[val] = val;
});
result = [];
for (let key in obj) {
result.push(key.split(",").map(Number));
}
return result;
};
const brektraning = function (nums, er) {
for (let i = er; i < nums.length; i++) {
path.push(nums[i]);
min = nums[i];
brektraning(nums, i + 1);
if (path.length >= 2 && grt(path)) road.push([...path]); //push不能为数组,所以只能先展开
path.pop();
while (nums[i + 1] && nums[i] === nums[i + 1]) i++; //去重
}
};
let grt = function (s) {
for (let i = 0; i < s.length - 1; i++) {
if (s[i] > s[i + 1]) return false;
}
return true;
};
第一想法
子集的方法,在返回结果时判断是否相同和是否大于,但内存和时间都很复杂。
不判断的话,会出现 [1,2,3,4,5,6,7,8,9,10,1,1,1,1,1]
这样的出错
困难
- 二维数组的去重
Set去重是比较数组中存入的值,当数组内值为简单数据类型,存入的就是值本身。比较的就是值本身。而二维数组存入的值为地址值,即使存入的相同,地址值也会不同。所以无法使用Set来进行去重。
- while (nums[i + 1] && nums[i] === nums[i + 1]) i++; 用这个去重是否有效?
无效!因为之前的
子集
的题目都是从大到小的排列好了的,这道题明显不是
卡哥的做法:
var findSubsequences = function(nums) {
let result = []
let path = []
function backtracing(startIndex) {
if(path.length > 1) {
result.push(path.slice())
}
let uset = []
for(let i = startIndex; i < nums.length; i++) {
if((path.length > 0 && nums[i] < path[path.length - 1]) || uset[nums[i] + 100]) {
continue
}
uset[nums[i] + 100] = true
path.push(nums[i])
backtracing(i + 1)
path.pop()
}
}
backtracing(0)
return result
};
思路打开!
- 同一父节点下的同层上使用过的元素就不能再使用了
uset[nums[i] + 100] 用哈希
6.全排列
/**
* @param {number[]} nums
* @return {number[][]}
*/
var permute = function (nums) {
let count = nums.length;
let result = [];
let path = [];
let uset = new Array(count);
uset.fill(0);
backtracing(nums, uset);
return result;
function backtracing(nums, uset) {
if (path.length === nums.length) {
result.push(path.slice());
}
for (let i = 0; i < nums.length; i++) {
if (uset[i]) {
continue;
}
path.push(nums[i]);
uset[i] = 1;
backtracing(nums, uset);
path.pop();
uset[i] = 0;
}
}
};
第一想法
因为数组里的数不重复,想的是哈希,如果是用过的,哈希为1。
但这个哈希竖着来,横着要清空,所以在pop()后要复原。
但是搞的时候没弄出来
backtracing在外面的时候,result为0,不知道为什么
思路
47.全排列 II
法一:
/**
* @param {number[]} nums
* @return {number[][]}
*/
var permuteUnique = function (nums) {
let count = nums.length;
let result = [];
let path = [];
let uset = new Array(count);
uset.fill(0);
backtracing(nums, uset);
let obj = {};
result.forEach((val) => {
// 此处不能用 obj.name = '属性值'的方式 因为此处的val是变量,不是固定值
obj[val] = val;
});
road = [];
for (let key in obj) {
road.push(key.split(",").map(Number));
}
return road;
function backtracing(nums, uset) {
if (path.length === nums.length) {
result.push(path.slice());
}
for (let i = 0; i < nums.length; i++) {
if (uset[i]) {
continue;
}
path.push(nums[i]);
uset[i] = 1;
backtracing(nums, uset);
path.pop();
uset[i] = 0;
}
}
};
法二:
/**
* @param {number[]} nums
* @return {number[][]}
*/
var permuteUnique = function (nums) {
let count = nums.length;
nums.sort((a,b)=>a-b)
let result = [];
let path = [];
let uset = new Array(count);
uset.fill(0);
backtracing(nums, uset);
return result;
function backtracing(nums, uset) {
if (path.length === nums.length) {
result.push(path.slice());
}
for (let i = 0; i < nums.length; i++) {
if (uset[i]) {
continue;
}
path.push(nums[i]);
uset[i] = 1;
backtracing(nums, uset);
path.pop();
uset[i] = 0;
while (nums[i + 1]!==undefined && nums[i] === nums[i + 1]) i++; //去重
}
}
};
第一想法
法一:嘿嘿,上一题的结果拿来去重。
法二:sort然后在上一题的基础上面去重
困难
- [0,1,0,0,9]过不了
while (nums[i + 1] && nums[i] === nums[i + 1]) i++; //去重
有问题,要写成nums[i + 1]!==undefined