39. 組合總和
題目連結:39. 組合總和
文件講解︰程式碼隨想錄(programmercarl.com)
影片講解︰組合總和
日期:2024-09-19
想法:組合總和型別題,允許重複使用元素,遞迴不+1就行。
Java程式碼如下:
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
public void backTracking(int[] candidates, int target, int startIndex){
if(target < 0){
return;
}
if(target == 0){
res.add(new ArrayList(path));
return;
}
for(int i = startIndex; i < candidates.length; i++){
path.add(candidates[i]);
target -= candidates[i];
backTracking(candidates, target, i);
path.removeLast();
target += candidates[i];
}
}
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backTracking(candidates, target, 0);
return res;
}
}
40.組合總和II
題目連結:40.組合總和II
文件講解︰程式碼隨想錄(programmercarl.com)
影片講解︰組合總和II
日期:2024-09-19
想法:去重挺麻煩,第一遍沒思路。
Java程式碼如下:
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
boolean[] used;
public void backTracking(int[] candidates, int target, int startIndex){
if(target < 0) return;
if(target == 0){
res.add(new ArrayList(path));
return;
}
for(int i = startIndex; i < candidates.length; i++){
if(i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false){
continue;
}
path.add(candidates[i]);
used[i] = true;
target -= candidates[i];
backTracking(candidates, target, i + 1);
path.removeLast();
target += candidates[i];
used[i] = false;
}
}
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
used = new boolean[candidates.length];
Arrays.fill(used, false);
Arrays.sort(candidates);
backTracking(candidates, target, 0);
return res;
}
}
總結:使用boolean used陣列來表示陣列中元素用沒用,先將陣列排序,使同樣的數字在一起,uesd陣列巧妙就巧妙在,如果used[i-1]為true,說明現在的i是在樹枝上,used[i-1]為false,說明i現在是在同一樹層上,這時判斷candidates[i] == candidates[i - 1]就能直到是不是在同一層用過前一個相同大小的數了,做到了去重。在理解了用used陣列的基礎上就可以考慮不用它:
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
public void backTracking(int[] candidates, int target, int startIndex){
if(target < 0) return;
if(target == 0){
res.add(new ArrayList(path));
return;
}
for(int i = startIndex; i < candidates.length; i++){
if(i > startIndex && candidates[i] == candidates[i - 1]){
continue;
}
path.add(candidates[i]);
target -= candidates[i];
backTracking(candidates, target, i + 1);
path.removeLast();
target += candidates[i];
}
}
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
backTracking(candidates, target, 0);
return res;
}
}
在(橫向)同一層的時候需要判斷前一個數是否和現在的相等,而遞迴(縱向)時就正常i+1往下走就行。
131.分割回文串
題目連結:131.分割回文串
文件講解︰程式碼隨想錄(programmercarl.com)
影片講解︰分割回文串
日期:2024-09-19
想法:構成樹的思路,橫向,切一刀,從不同位置從左到右,縱向每一層在之前切一刀的位置的後面加1刀。
Java程式碼如下:
class Solution {
List<List<String>> res = new ArrayList<>();
List<String> path = new ArrayList<>();
private void backtracking(String s, int startIndex, StringBuilder sb){
if (startIndex >= s.length()){
res.add(new ArrayList<>(path));
return;
}
for (int i = startIndex; i < s.length(); i++){
sb.append(s.charAt(i));
if (check(sb)){
path.add(sb.toString());
backtracking(s, i + 1, new StringBuilder());
path.removeLast();
}
}
}
private boolean check(StringBuilder sb){
for(int i = 0, j = sb.length() - 1; i < j; i++, j--){
if(sb.charAt(i) != sb.charAt(j)) return false;
}
return true;
}
public List<List<String>> partition(String s){
backtracking(s, 0, new StringBuilder());
return res;
}
}
總結:判斷迴文雙指標。