一、复原IP地址
此题关键在于分割字符串的同时要加上分割点,注意起始位置startIndex 为i + 2
终止条件为当点数等于3的时候只需要判断后面的子串是否合法即可
/**
* @param {string} s
* @return {string[]}
*/
var restoreIpAddresses = function(s) {
let result = []
function isValid(s, start, end) {
if(start > end) {
return false
}
if(s[start] === '0' && start !== end) {
return false
}
let num = 0
for(let i = start; i <= end; i++) {
if(s[i] > '9' || s[i] < 0) {
return false
}
num = num * 10 + Number(s[i])
if(num > 255) {
return false
}
}
return true
}
function backtracking(s, startIndex, pointNum) {
if(pointNum === 3) {
if(isValid(s, startIndex, s.length - 1)) {
result.push(s)
}
return
}
for(let i = startIndex; i < s.length; i++) {
if(isValid(s, startIndex, i)) {
backtracking(s.substring(0, i + 1) + '.' + s.substring(i + 1), i + 2, pointNum + 1)
} else {
break
}
}
}
if(s.length > 12) {
return []
}
backtracking(s, 0, 0)
return result
};
二、子集
和之前的组合问题不同,子集相当于把所有子节点记录下来,需要遍历整颗树,所以不需要剪枝
/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsets = function(nums) {
let path = []
let result = []
function backtracking(startIndex) {
if(startIndex > nums.length) {
return
}
result.push([...path])
for(let i = startIndex; i < nums.length; i++) {
path.push(nums[i])
backtracking(i + 1)
path.pop()
}
}
backtracking(0)
return result
};
三、子集2
此题和子集的区别在于集合是可以有重复的,需要去重,所以需要排序,还有就是树层去重和树枝去重的理解,和之前组合问题的去重一样
/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsetsWithDup = function (nums) {
let path = []
let result = []
nums.sort((x, y) => x - y)
function backtracking(startIndex) {
if (startIndex > nums.length) {
return
}
result.push([...path])
for (let i = startIndex; i < nums.length; i++) {
if(i > startIndex && nums[i] === nums[i - 1]) {
continue
}
path.push(nums[i])
backtracking(i + 1)
path.pop()
}
}
backtracking(0)
return result
};