一、LC39. 组合总和
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
递归:终止条件,sum = target
优化策略:对数组进行排序,这样循环过程中如果遇到一个元素加上之前元素和>target,那么其后的元素都不需要检验了。每次循环遍历都从当前元素开始,这样就能去重。

class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> tmp = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
for (int i = 0; i < tmp.size(); i++) {
System.out.print(tmp.get(i));
}
helper(candidates, target, 0);
return result;
}
public void helper(int[] candidates, int target, int start) {
if (target == 0) {
result.add(new ArrayList<>(tmp));
return;
}
for (int i = start; i < candidates.length; i++) {
if (target - candidates[i] < 0) {
break;
}
tmp.add(candidates[i]);
helper(candidates, target - candidates[i], i);
tmp.remove(tmp.size() - 1);
}
}
}
二、LC40.组合总和II
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
有重复元素
递归:终止条件,sum = target
优化策略:对数组进行排序,这样循环过程中如果遇到一个元素加上之前元素和>target,那么其后的元素都不需要检验了。每次循环遍历都从当前元素开始,这样就能去重。
其次,为了防止重复的元素分支结果重复计算,在每一层上,如果当前元素和上一个元素相同,且当前元素所对应的index>这一层的startIndex,那么目前这个数字就跳过。
不然[1,1,2],第二个1永远不会被考虑进去,因为i=1>0且满足candidates[i] == candidates[i - 1]。

class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
helper(candidates, target, 0);
return result;
}
public void helper(int[] candidates, int target, int start) {
if (target == 0) {
result.add(new ArrayList<>(path));
return;
}
for (int i = start; i < candidates.length; i++) {
if (i > start && candidates[i] == candidates[i - 1]) {
System.out.println(candidates[i]);
continue;
}
if (target - candidates[i] < 0) {
break;
}
path.add(candidates[i]);
helper(candidates, target - candidates[i], i + 1);
path.remove(path.size() - 1);
}
}
}
三、LC131.分割回文串
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
对于每个字符串,每个位置都进行切割,切割的字段检查是否是回文数。如果不是,放弃当前排列向下搜索的可能性,如果是,那么继续向下搜索。
class Solution {
List<List<String>> result = new ArrayList<>();
List<String> path = new ArrayList<>();
public List<List<String>> partition(String s) {
backward(s, 0);
return result;
}
public void backward(String s, int startIndex) {
if (startIndex >= s.length()) {
result.add(new ArrayList<>(path));
return;
}
for (int i = startIndex; i < s.length(); i++) {
if (!isPalindrome(s.substring(startIndex, i + 1))) {
continue;
}
path.add(s.substring(startIndex, i + 1));
backward(s, i + 1);
path.remove(path.size() - 1);
}
}
//判断回文数
public boolean isPalindrome(String s) {
if (s.length() == 1) {
return true;
}
int left = 0;
int right = s.length() - 1;
while (left < right) {
if (s.charAt(left) != s.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
}
本文介绍了LeetCode中的三个问题:使用递归解决LC39组合总和和LC40组合总和II,以及如何通过字符串处理找出LC131分割回文串。重点在于递归策略、排序去重和避免重复计算。
475

被折叠的 条评论
为什么被折叠?



