回溯问题学习总结

回溯问题

三种情况

每种情况都有子集,组合,排列三种题型

无重复元素不可复选

//子集问题
static List<list<integer>> res=new LinkedList<>();
 &#xA0; &#xA0;static LinkedList<integer> track=new LinkedList<>();
 &#xA0; &#xA0;//&#x65E0;&#x91CD;&#x590D;&#x5143;&#x7D20;
 &#xA0; &#xA0;public static List<list<integer>> subsets(int[] nums) {
 &#xA0; &#xA0; &#xA0; &#xA0;back(nums,0);
 &#xA0; &#xA0; &#xA0; &#xA0;return res;
 &#xA0;  }
&#x200B;
 &#xA0; &#xA0;static void back(int[] nums,int start){
 &#xA0; &#xA0; &#xA0; &#xA0;res.add(new LinkedList<>(track));
 &#xA0; &#xA0; &#xA0; &#xA0;for (int i=start;i<nums.length;i++){    track.add(nums[i]);  back(nums,i+1);  track.removelast(); } ​ 组合问题 static list<list<integer>> res=new LinkedList<>();
 &#xA0; &#xA0;static LinkedList<integer> track=new LinkedList<>();
 &#xA0; &#xA0;public static List<list<integer>> combine(int n, int k) {
 &#xA0; &#xA0; &#xA0; &#xA0;backtrack(n,1,k);
 &#xA0; &#xA0; &#xA0; &#xA0;return res;
 &#xA0;  }
 &#xA0; &#xA0;static void backtrack(int n,int start,int k){
 &#xA0; &#xA0; &#xA0; &#xA0;if(track.size()==k){
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;res.add(new LinkedList<>(track));
 &#xA0; &#xA0; &#xA0;  }
 &#xA0; &#xA0; &#xA0; &#xA0;for (int i=start;i<=n;i++){    track.add(i);  backtrack(n,i+1,k);  track.removelast(); } 排列问题 static list<list<integer>> res=new LinkedList<>();
 &#xA0; &#xA0;static LinkedList<integer> track=new LinkedList<>();
 &#xA0; &#xA0;public static List<list<integer>> permute(int[] nums) {
 &#xA0; &#xA0; &#xA0;back(nums,track);
 &#xA0; &#xA0; &#xA0;return res;
 &#xA0;  }
&#x200B;
 &#xA0; &#xA0;static void back(int[] nums,LinkedList<integer> track){
 &#xA0; &#xA0; &#xA0; &#xA0;if(track.size()== nums.length){
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;res.add(new LinkedList<>(track));
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;return;
 &#xA0; &#xA0; &#xA0;  }
 &#xA0; &#xA0; &#xA0; &#xA0;for (int i=0;i<nums.length;i++){    if(track.contains(nums[i])) continue;  track.add(nums[i]);  back(nums,track);  track.removelast(); } }< code></nums.length;i++){></integer></list<integer></integer></=n;i++){></list<integer></integer></nums.length;i++){></list<integer></integer></list<integer>

有重复元素不可复选

//&#x5B50;&#x96C6;&#x95EE;&#x9898;
List<list<integer>> res = new LinkedList<>();
LinkedList<integer> track = new LinkedList<>();
&#x200B;
public List<list<integer>> subsetsWithDup(int[] nums) {
 &#xA0; &#xA0;// &#x5148;&#x6392;&#x5E8F;&#xFF0C;&#x8BA9;&#x76F8;&#x540C;&#x7684;&#x5143;&#x7D20;&#x9760;&#x5728;&#x4E00;&#x8D77;
 &#xA0; &#xA0;Arrays.sort(nums);
 &#xA0; &#xA0;backtrack(nums, 0);
 &#xA0; &#xA0;return res;
}
&#x200B;
void backtrack(int[] nums, int start) {
 &#xA0; &#xA0;// &#x524D;&#x5E8F;&#x4F4D;&#x7F6E;&#xFF0C;&#x6BCF;&#x4E2A;&#x8282;&#x70B9;&#x7684;&#x503C;&#x90FD;&#x662F;&#x4E00;&#x4E2A;&#x5B50;&#x96C6;
 &#xA0; &#xA0;res.add(new LinkedList<>(track));
 &#xA0;
 &#xA0; &#xA0;for (int i = start; i < nums.length; i++) {
 &#xA0; &#xA0; &#xA0; &#xA0;// &#x526A;&#x679D;&#x903B;&#x8F91;&#xFF0C;&#x503C;&#x76F8;&#x540C;&#x7684;&#x76F8;&#x90BB;&#x6811;&#x679D;&#xFF0C;&#x53EA;&#x904D;&#x5386;&#x7B2C;&#x4E00;&#x6761;
 &#xA0; &#xA0; &#xA0; &#xA0;if (i > start && nums[i] == nums[i - 1]) {
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;continue;
 &#xA0; &#xA0; &#xA0;  }
 &#xA0; &#xA0; &#xA0; &#xA0;track.addLast(nums[i]);
 &#xA0; &#xA0; &#xA0; &#xA0;backtrack(nums, i + 1);
 &#xA0; &#xA0; &#xA0; &#xA0;track.removeLast();
 &#xA0;  }
}
//&#x7EC4;&#x5408;&#x95EE;&#x9898;
List<list<integer>> res = new LinkedList<>();
&#x200B;
LinkedList<integer> track = new LinkedList<>();
&#x200B;
int trackSum = 0;
&#x200B;
public List<list<integer>> combinationSum2(int[] candidates, int target) {
 &#xA0; &#xA0;if (candidates.length == 0) {
 &#xA0; &#xA0; &#xA0; &#xA0;return res;
 &#xA0;  }
 &#xA0; &#xA0;// &#x5148;&#x6392;&#x5E8F;&#xFF0C;&#x8BA9;&#x76F8;&#x540C;&#x7684;&#x5143;&#x7D20;&#x9760;&#x5728;&#x4E00;&#x8D77;
 &#xA0; &#xA0;Arrays.sort(candidates);
 &#xA0; &#xA0;backtrack(candidates, 0, target);
 &#xA0; &#xA0;return res;
}
&#x200B;
void backtrack(int[] nums, int start, int target) {
 &#xA0; &#xA0; &#xA0; &#xA0;if (trackSum == target) {
 &#xA0; &#xA0; &#xA0; &#xA0;res.add(new LinkedList<>(track));
 &#xA0; &#xA0; &#xA0; &#xA0;return;
 &#xA0;  }
 &#xA0;
 &#xA0; &#xA0;if (trackSum > target) {
 &#xA0; &#xA0; &#xA0; &#xA0;return;
 &#xA0;  }
&#x200B;
 &#xA0;
 &#xA0; &#xA0;for (int i = start; i < nums.length; i++) {
 &#xA0; &#xA0; &#xA0; &#xA0;// &#x526A;&#x679D;&#x903B;&#x8F91;&#xFF0C;&#x503C;&#x76F8;&#x540C;&#x7684;&#x6811;&#x679D;&#xFF0C;&#x53EA;&#x904D;&#x5386;&#x7B2C;&#x4E00;&#x6761;
 &#xA0; &#xA0; &#xA0; &#xA0;if (i > start && nums[i] == nums[i - 1]) {
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;continue;
 &#xA0; &#xA0; &#xA0;  }
 &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;track.add(nums[i]);
 &#xA0; &#xA0; &#xA0; &#xA0;trackSum += nums[i];
 &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;backtrack(nums, i + 1, target);
 &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;track.removeLast();
 &#xA0; &#xA0; &#xA0; &#xA0;trackSum -= nums[i];
 &#xA0;  }
}
//&#x6392;&#x5217;&#x95EE;&#x9898;
List<list<integer>> res = new LinkedList<>();LinkedList<integer> track = new LinkedList<>();
boolean[] used;
&#x200B;
public List<list<integer>> permuteUnique(int[] nums) {
 &#xA0; &#xA0;// &#x5148;&#x6392;&#x5E8F;&#xFF0C;&#x8BA9;&#x76F8;&#x540C;&#x7684;&#x5143;&#x7D20;&#x9760;&#x5728;&#x4E00;&#x8D77;
 &#xA0; &#xA0;Arrays.sort(nums);
 &#xA0; &#xA0;used = new boolean[nums.length];
 &#xA0; &#xA0;backtrack(nums);
 &#xA0; &#xA0;return res;
}
&#x200B;
void backtrack(int[] nums) {
 &#xA0; &#xA0;if (track.size() == nums.length) {
 &#xA0; &#xA0; &#xA0; &#xA0;res.add(new LinkedList(track));
 &#xA0; &#xA0; &#xA0; &#xA0;return;
 &#xA0;  }
&#x200B;
 &#xA0; &#xA0;for (int i = 0; i < nums.length; i++) {
 &#xA0; &#xA0; &#xA0; &#xA0;if (used[i]) {
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;continue;
 &#xA0; &#xA0; &#xA0;  }
 &#xA0; &#xA0; &#xA0; &#xA0;// &#x65B0;&#x6DFB;&#x52A0;&#x7684;&#x526A;&#x679D;&#x903B;&#x8F91;&#xFF0C;&#x56FA;&#x5B9A;&#x76F8;&#x540C;&#x7684;&#x5143;&#x7D20;&#x5728;&#x6392;&#x5217;&#x4E2D;&#x7684;&#x76F8;&#x5BF9;&#x4F4D;&#x7F6E;
 &#xA0; &#xA0; &#xA0; &#xA0;if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) {
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;continue;
 &#xA0; &#xA0; &#xA0;  }
 &#xA0; &#xA0; &#xA0; &#xA0;track.add(nums[i]);
 &#xA0; &#xA0; &#xA0; &#xA0;used[i] = true;
 &#xA0; &#xA0; &#xA0; &#xA0;backtrack(nums);
 &#xA0; &#xA0; &#xA0; &#xA0;track.removeLast();
 &#xA0; &#xA0; &#xA0; &#xA0;used[i] = false;
 &#xA0;  }
}</list<integer></integer></list<integer></list<integer></integer></list<integer></list<integer></integer></list<integer>

无重复元素可复选

&#x200B;
&#x200B;
//&#x5B50;&#x96C6;&#x95EE;&#x9898;
List<list<integer>> res = new LinkedList<>();
&#x200B;
LinkedList<integer> track = new LinkedList<>();
&#x200B;
int trackSum = 0;
&#x200B;
public List<list<integer>> combinationSum(int[] candidates, int target) {
 &#xA0; &#xA0;if (candidates.length == 0) {
 &#xA0; &#xA0; &#xA0; &#xA0;return res;
 &#xA0;  }
 &#xA0; &#xA0;backtrack(candidates, 0, target);
 &#xA0; &#xA0;return res;
}
&#x200B;
&#x200B;
void backtrack(int[] nums, int start, int target) {
 &#xA0;
 &#xA0; &#xA0;if (trackSum == target) {
 &#xA0; &#xA0; &#xA0; &#xA0;res.add(new LinkedList<>(track));
 &#xA0; &#xA0; &#xA0; &#xA0;return;
 &#xA0;  }
 &#xA0;
 &#xA0; &#xA0;if (trackSum > target) {
 &#xA0; &#xA0; &#xA0; &#xA0;return;
 &#xA0;  }
&#x200B;
 &#xA0;
 &#xA0; &#xA0;for (int i = start; i < nums.length; i++) {
 &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;trackSum += nums[i];
 &#xA0; &#xA0; &#xA0; &#xA0;track.add(nums[i]);
 &#xA0;
 &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;backtrack(nums, i, target);
 &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;trackSum -= nums[i];
 &#xA0; &#xA0; &#xA0; &#xA0;track.removeLast();
 &#xA0;  }
}
&#x200B;
//&#x6392;&#x5217;&#x95EE;&#x9898;
List<list<integer>> res = new LinkedList<>();
LinkedList<integer> track = new LinkedList<>();
&#x200B;
public List<list<integer>> permuteRepeat(int[] nums) {
 &#xA0; &#xA0;backtrack(nums);
 &#xA0; &#xA0;return res;
}
&#x200B;
&#x200B;
void backtrack(int[] nums) {
 &#xA0;
 &#xA0; &#xA0;if (track.size() == nums.length) {
 &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;res.add(new LinkedList(track));
 &#xA0; &#xA0; &#xA0; &#xA0;return;
 &#xA0;  }
&#x200B;
 &#xA0;
 &#xA0; &#xA0;for (int i = 0; i < nums.length; i++) {
 &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;track.add(nums[i]);
 &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;backtrack(nums);
 &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;track.removeLast();
 &#xA0;  }</list<integer></integer></list<integer></list<integer></integer></list<integer>

Original: https://www.cnblogs.com/zz01/p/16616245.html
Author: 山野村夫01
Title: 回溯问题学习总结

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/622138/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球