今天问题还是挺严重的,自己以为会的其实都是模棱两可,就包括回溯算法,回溯算法最重要的是对于状态的暂停,状态的汇总,和开始的标志,首先第一题,限制条件是数字之和为target,允许的条件是可以无限次数的读取数组中的元素,但是解集不能重复,所以不妨给他设立标签,就是每轮都进行筛选 代码如下
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.List;
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
int len = candidates.length;
// 排序是为了提前终止搜索
Arrays.sort(candidates);
dfs(candidates, len, target, 0, new ArrayDeque<>(), res);
return res;
}
/**
* @param candidates 数组输入
* @param len 输入数组的长度,冗余变量
* @param residue 剩余数值
* @param begin 本轮搜索的起点下标
* @param path 从根结点到任意结点的路径
* @param res 结果集变量
*/
private void dfs(int[] candidates,
int len,
int residue,
int begin,
Deque<Integer> path,
List<List<Integer>> res) {
if (residue == 0) {
// 由于 path 全局只使用一份,到叶子结点的时候需要做一个拷贝
res.add(new ArrayList<>(path));
return;
}
for (int i = begin; i < len; i++) {
// 在数组有序的前提下,剪枝
if (residue - candidates[i] < 0) {
break;
}
path.addLast(candidates[i]);
dfs(candidates, len, residue - candidates[i], i, path, res);
path.removeLast();
}
}
}
每轮都是i 也就是说 每轮都从原地开始找,实在找不到再去i+1 也就是下一轮进行寻找。
而第二题!限制条件呢 , 主要是长度问题,字符串必须全部读取了,相当于说生成字符串的长度与原来字符串相同,但是每个元素只能读取一次,那么我们就必须进行元素读取的限制了,每次只能读一个,我们就用visited数组,进行元素标记,读取过得就进行标记,进行嵌套读取就行,循环的条件是对于visited数组的遍历,每次都找到没有标记的visited数组就可以,但是有人会问,每次都是从0开始,是怎么一步一步形成所有的字符串呢,解答如下,因为虽然每次都是从0开始,但是我们的标准是对于字符串长度的限制,0长度时候从0开始,1长度也是从0开始,1长度的时候,是对于上一层选取了一个字符进行1长度的筛选。代码如下:
public String[] permutation(String s) {
if(s.equals("")) return new String[0];
char[] schars=s.toCharArray();
boolean[] visited=new boolean[schars.length];
Set<String>set=new HashSet<>();
dfs_per(set,"",visited,schars);
String[] res= new String[set.size()];
return set.toArray(res);
}
public void dfs_per(Set<String>res,String str,boolean[] visited,char[] sc){
if(str.length()==sc.length){
res.add(new String(str));
System.out.println(str);
return;
}
for(int i=0;i<sc.length;i++){
if(visited[i]==true) continue;
visited[i]=true;
dfs_per(res,str+sc[i],visited,sc);
visited[i]=false;
}
}
意思是 每次循环结束的时候,找到上一层的循环时候,我必须解除这一层的遍历标记,然后默认上一层元素从0变成了1,然后再把1进行标记,再进行搜索,完成了遍历所有元素的任务!!!!!~