回溯算法应用组合里面:对应力扣77题
利用的就是回溯算法,去深探找到组合
public static List<List<Integer>> result = new ArrayList<>();
public static LinkedList<Integer> path = new LinkedList<>();
public static void main(String[] args){
dfs(4,2,1);
System.out.println(result);
}
public static void dfs(int n,int k,int startindex){
if(path.size() == k){
result.add(new ArrayList<>(path));
return;
}
for(int i = startindex;i<=n;i++){
path.add(i);
dfs(n,k,i+1);
path.removeLast();
}
}
组合数的plus版本,心里挺有感触:
public static int[] num = {2,3,5};
public static List<List<Integer>> result = new ArrayList<>();
public static LinkedList<Integer> path = new LinkedList<>();
public static void main(String[] args){
backtracking(0,8,0);
System.out.println(result);
}
public static void backtracking(int sum,int target,int index){
if(sum > target){
return;
}
if(sum == target){
result.add(new ArrayList<>(path));
return;
}
for(int i = index;i < num.length;i++){
sum += num[i];
path.add(num[i]);
backtracking(sum,target,i);
sum -= num[i];
path.removeLast();
}
}
题目升级版:在母题基础上进行升级,加入限制条件,组合和为特定值:
public static List<List<Integer>> result = new ArrayList<>();
public static LinkedList<Integer> path = new LinkedList<>();
public static void main(String[] args){
dfs(10,2,1);
System.out.println(result);
}
public static void dfs(int n,int k,int startindex){
if(path.size() == k && SumNum(path,n)){
result.add(new ArrayList<>(path));
return;
}
for(int i = startindex;i<=9;i++){
path.add(i);
dfs(n,k,i+1);
path.removeLast();
}
}
public static boolean SumNum(LinkedList<Integer> p,int n){
int sum = 0;
for(int i = 0;i<p.size();i++){
sum += p.get(i);
}
if(sum == n){
return true;
}else{
return false;
}
}
一个电话号码的回溯类型题目:没有组合数要求,可以重复被选取
public static String PhoneWord[] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv", "wxyz"};
public static LinkedList<String> path = new LinkedList<>();
public static List<List<String>> result = new ArrayList<>();
public static void main(String[] args){
backtracking("79",0);
System.out.println(result);
}
public static void backtracking(String digit,int index){
if(index == digit.length()){
result.add(new ArrayList<String>(path));
return;
}
int d = digit.charAt(index) - '0';
String s = PhoneWord[d];
for(int i = 0;i<s.length();i++){
path.add(s.substring(i,i+1));
backtracking(digit,index+1);
path.removeLast();
}
}
回溯问题之去重组合问题:重在使用了uesd的数组来进行去重
public static List<List<Integer>> result = new ArrayList<>();
public static LinkedList<Integer> path = new LinkedList<>();
public static void main(String[] args){
int[] num = {10,1,2,7,6,1,5};
boolean[] uesd = new boolean[num.length];
Arrays.sort(num);
backtracking(num,0,8,0,uesd);
System.out.println(result);
}
public static void backtracking(int[] num,int sum,int target,int index,boolean[] uesd){
if(sum == target){
result.add(new ArrayList<>(path));
return;
}
for(int i = index;i < num.length && sum+num[i] <= target;i++){
if((i > 0) && (num[i] == num[i - 1]) && (uesd[i - 1] == false)){
continue;
}
sum += num[i];
path.add(num[i]);
uesd[i] = true;
backtracking(num,sum,target,i+1,uesd);
uesd[i] = false;
sum -= num[i];
path.removeLast();
}
}
数学问题之集合子集:
public static List<List<Integer>> result = new ArrayList<>();
public static LinkedList<Integer> path = new LinkedList<>();
public static void main(String[] args){
int[] num = {1,2,3};
backtracking(num,0);
System.out.println(result);
}
public static void backtracking(int[] num,int startIndex){
result.add(new ArrayList<>(path));
if(startIndex > num.length){
return;
}
for(int i = startIndex;i < num.length;i++){
path.add(num[i]);
backtracking(num,i+1);
path.removeLast();
}
}
回溯问题之排列组合:
public static List<List<Integer>> result = new ArrayList<>();
public static LinkedList<Integer> path = new LinkedList<>();
public static void main(String[] args){
int[] num = {1,2,3};
boolean[] used = new boolean[num.length];
backtracking(num,used);
System.out.println(result);
}
public static void backtracking(int[] num,boolean[] used){
if(path.size() == num.length){
result.add(new ArrayList<>(path));
return;
}
for(int i = 0;i<num.length;i++){
if(used[i] == true){
continue;
}
used[i] = true;
path.add(num[i]);
backtracking(num,used);
used[i] = false;
path.removeLast();
}
}
回溯算法这一部分要告一段落了,通过这几天的学习,对于算法学习已经有很深刻的认识了。回溯模型具有一定的模板。。。
学习来自代码随想录
本文介绍了回溯算法在解决组合问题中的应用,从经典的组合生成,到加入限制条件的组合求和,再到电话号码的字母映射,以及去重组合和排列组合问题。通过一系列递归实现的回溯函数,展示了回溯算法如何有效地搜索解空间并避免无效路径。此外,还探讨了如何使用标记数组避免重复元素,以及解决子集和集合排列问题。这些例子深入浅出地揭示了回溯算法的模板性质及其在解决组合问题上的广泛适用性。
4271

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



