【感悟】写题越来越快啦,而且可以自己写出来了,每天努力一点点,真的可以慢慢变厉害!希望看到我的 blog 的有缘人也可以努力,真的没有想象中的难!
-
93.复原IP地址
【思路】这道题的重点在于在哪加.
,递归的起始位置要考虑清楚加了.
之后的下标,终止条件是小于 255 和首位不能为 0 。判断结束是要遍历到最后并且path
长度为 4 。(因为我的方法是最后添加进res
时把path
数组改成字符串并添加.
,所以不用考虑递归时开始的下标问题)var restoreIpAddresses = function(s) { let res = [], path = []; const isValid = (start, end) => { // 开头不能为 0 if (start !== end && s[start] === '0') return false; // 不能大于 255 if (s.slice(start, end + 1) > 255) return false; return true; } const backtracking = startIndex => { if (path.length === 4 && startIndex > s.length -1) { if (isValid(startIndex, s.length - 1)) { res.push(path.join('.')); } } for (let i = startIndex; i < s.length; i++) { if (!isValid(startIndex, i)) return; path.push(s.slice(startIndex, i + 1)); backtracking(i + 1); path.pop(); } } backtracking(0); return res; };
-
78.子集
【思路】之前我们做的递归组合问题,抽象成一个 N 叉树,组合问题收集的是 N 叉树的所有子节点,那么求数组子集就是收集 N 叉树的所有节点。res
收集结果就得在每次path
数组完成一次收集之后,才能得到每个节点的值。var subsets = function(nums) { let path = [], res = [[]]; const backtracking = startIndex => { if (startIndex === nums.length) return; for (let i = startIndex; i < nums.length; i++) { path.push(nums[i]); res.push([...path]); backtracking(i + 1); path.pop(); } } backtracking(0); return res; };
-
90.子集II
【思路】这道题比上一道题多了一个对于重复的判断。对于重复问题:老套路就是先对数组进行排序,再使用used
数组记录已经使用过的元素,就可以解决重复问题。
展示的两种其实并没有什么区别,只是写的时候发现有 bug,修改时,发现res
push 值的位置不一样,那么对于终止条件的判断也不一样,其实也就是改 bug 的两种方式罢了,但自己写错了,就记录一下子~var subsetsWithDup = function(nums) { let res = [], path = [], used = new Array(nums.length).fill(0); sortNums = nums.sort((a, b) => a - b); const backtracking = (startIndex, used) => { if (startIndex > sortNums.length) return; res.push([...path]); for (let i = startIndex; i < sortNums.length; i++) { if (sortNums[i] === sortNums[i -1] && used[i - 1] === 0) continue; path.push(sortNums[i]); used[i] = 1; backtracking(i + 1, used); path.pop(); used[i] = 0; } } backtracking(0, used); return res; }; var subsetsWithDup = function(nums) { let res = [[]], path = [], used = new Array(nums.length).fill(0), sortNums = nums.sort((a, b) => a - b); const backtracking = (startIndex, used) => { if (startIndex >= sortNums.length) return; // 如果这里是大于的话,那么 res 初始值就等于 [],因为当等于 sortNums.length 的时候会 push 一次空(例如上一个方法) for (let i = startIndex; i < sortNums.length; i++) { if (sortNums[i] === sortNums[i -1] && used[i - 1] === 0) continue; path.push(sortNums[i]); res.push([...path]); used[i] = 1; backtracking(i + 1, used); path.pop(); used[i] = 0; } } backtracking(0, used); return res; };
参考代码随想录:https://www.programmercarl.com/