public List<List> findLadders(String start, String end, Set dict){
results = new ArrayList<List>();
if(dict.size() == 0){
return results;
}
int min = Integer.MAX_VALUE;
//队列辅助树的宽度搜索
Queue<String> queue = new ArrayList<String>();
queue.add(start);//往队列中加入开始的元素
//存放的是树中每一个结点到达初始节点的刚开始的距离的值
Map<String,Integer> ladder = new HashMap<String,Integer>();
for(String string:dict){
ladder.put(string,Integer.MAX_VALUE);
}
ladder.put(start,0);
dict.add(end);
//宽度优先搜索算法==迪杰斯特拉算法
while(!queue.isEmpty()){
String word = queue.poll();//弹出队头元素
int step = ladder.get(word) + 1;//表示的步数要加一
if(step > min){
break;
}
for(int i = 0; i < word.length()l i ++){
StringBuilder builder = new StringBuilder(word);
for(char ch = 'a'; ch <= 'z'; ch++){
//对于每个弹出队列中的单词一位位地进行替换操作
builder.setCharAt(i,ch);
String new_world = builder.tostring();
//路径中存在着到达当前这个新单词的路径
if(ladder.containsKey(new_world)){
//判断当前的路径是否是到达new_world的最小值
//如果是的话则要替换,否则保持不变
if(step > ladder.get(new_world)){
continue;//表示此处是直接跳过
}
//比之前的要小,所以现在要将该新单词加入到队列中去,可以作为构造树的节点
else if(step < ladder.get(new_world)){
queue.add(new_world);
//记录初始结点到目前结点的最小步数,和queue是同步进行操作的
ladder.put(new_world,step);
}
//构建邻接矩阵(目的在于构建路径,采用的是回溯的方法)
//如果在矩阵中已经存在了的话,在新单词后面可以到达的列表之中
//加上这个新的单词
if(map.containsKey(new_world)){
map.get(new_world).add(word);
}
//不存在的话要将新的单词加入到map集合之中
else{
List<String> list = new LinkedList<String>();
list.add(word);
map.put(new_world,list);
}
//如果已经到达了目的单词的话
if(new_world.equals(end)){
min = step;
}
}
}
}
}
//回溯得到所有的路径结果
LinkedList<String> result = new LinkedList<String>();
backTrace(end,start,result);
return result;
}
//word代表的是要到达的目标节点
private void backTrace(String word, String start,List<String> list){
//目标节点和起点节点的值相等,表示的是递归的出口
if(word.equals(start)){
list.add(0,start);
results.add(new ArrayList<String>(list));
list.remove(0);
return;
}
//将第一个单词添加到list集合之中
list.add(0,word);
//对每一个word可以到达的结点进行递归
if(map.get(word) != null){
for(String s:map.get(word)){
backTrace(s,start,list);
}
}
//回溯当前路径已经遍历完了,该换下一条路径了
list.remove(0);
}
126.Word Ladder II
最新推荐文章于 2020-05-10 10:41:33 发布