一、39 组合总和
思路:和组合问题基本相似,只不过是将i+1替换成为了i,这样认为它可以从当前的这一个元素重复使用。
代码:
var combinationSum = function(candidates, target) {
var result = []
var backtracking = function(startIndex, path) {
var sum = 0;
for (let i=0; i<path.length; i++) {
sum += path[i];
}
if (sum > target) {
return;
}
else if (sum == target) {
result.push(path.slice(0));
return;
}
for (let i=startIndex; i<candidates.length; i++) {
path.push(candidates[i]);
// 这里,不是i+1而是i,代表可以选择重复的
backtracking(i, path);
path.pop();
}
}
backtracking(0, []);
return result;
};
二、40 组合总和II
思路:如果是不能出现相同的数据,则一层当中不能两次采用相同的进入循环
代码:
var combinationSum2 = function(candidates, target) {
var result = [];
// 箭头函数只有一行不需要写大括号,且直接返回,不然需要写return
candidates.sort((a, b) => b-a);
var backtracking = function(startIndex, path) {
var sum = 0;
for (let i=0; i<path.length; i++) {
sum += path[i];
}
if (sum > target) {
return;
}
else if (sum == target) {
result.push(path.slice(0));
return;
}
for (let i=startIndex; i<candidates.length; i++) {
// 一层中不能有两个相同的数进入递归
if (i > startIndex && candidates[i] == candidates[i - 1]) {
continue;
}
path.push(candidates[i]);
// 不能重复使用同一个数,所以从下一个开始
backtracking(i+1, path);
path.pop();
}
}
backtracking(0, []);
return result;
};
三、131 分割回文串
思路:如果是一个集合求组合的话,需要startIndex,如果是多个集合独立开求组合的话,就不需要startIndex,这里是定义了一个是否为回文字符串的函数,如果从startIndex开始的一段字符串是回文串,那么就可以,然后从下一个字符开始递归。
代码:
var partition = function(s) {
var result = [];
var isPalindrome = function(str) {
var arr = Array.from(str);
var left = 0;
var right = str.length - 1;
while (left <= right) {
if (arr[right] != arr[left]) {
return false;
}
right--;
left++;
}
return true;
}
var backtracking = function(startIndex, path) {
if (startIndex >= s.length) {
result.push(path.slice(0));
return;
}
for (let i=startIndex; i<s.length; i++) {
if (isPalindrome(s.slice(startIndex, i+1))) {
path.push(s.slice(startIndex, i+1));
}
// 如果当前的子串不是回文子串,则不需要对后面的进行递归,而是看看向右移一位会不会是回文串
else {
continue;
}
backtracking(i+1, path);
path.pop();
}
}
backtracking(0, []);
return result;
};
今日学习时长:1.5h左右
总结:今天的题相对有点难,包括重复数值的选取等等,再刷的时候需要再注意一下131题。