Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord toendWord, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the word list

For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

Return

  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
先建好图,然后用dijsktra算法求出所有最短路,由于记录的是前驱节点所以在最后反转路径。

最近做完题习惯看看discuss,发现了别的速度快的方法。

public class Solution {
    boolean able_reach(String str1, String str2){
		int diff = 0;
		int i,len = str1.length();
		for(i = 0; i < len; ++ i){
			if(str1.charAt(i) != str2.charAt(i)){
				++diff;
			}
		}
		return diff==1;
	}
	
	List<Integer>[] BuildGraph(String beginWord, String endWord, Set<String> wordList, String[] hp){
		ArrayList<Integer>[] graph = new ArrayList[wordList.size()+2];
		int idx = 0;

		//establish relationship between idx and string
		hp[idx] = beginWord;
		for(String str:wordList){
			++idx;
			hp[idx] = str;
		}
		++idx;
		hp[idx] = endWord;
		
		//build map
		int idx1,idx2;
		for(int i = 0; i < graph.length; ++i){
			graph[i] = new ArrayList<Integer>();
		}
		for(idx1 = 0; idx1 < graph.length; ++idx1){
			for(idx2 = idx1 + 1; idx2 < graph.length; ++idx2){
				if (able_reach(hp[idx1],hp[idx2])){
					graph[idx1].add(idx2);
					graph[idx2].add(idx1);
				}
			}
		}
		return graph;
	}
	
	List<List<String>> print_paths(ArrayList<Integer>[] pre, String[] word_map, List<List<String>> paths){
		ArrayList<String> path = new ArrayList<String>();
		path.add(word_map[word_map.length - 1]);
		print_path(pre,word_map.length-1,path,paths,word_map);
		return paths;
	}
	
	void print_path(ArrayList<Integer>[] pre,int node,ArrayList<String> path, List<List<String>> paths, String[] word_map){
		if(node == 0){
			ArrayList<String> temp_path = new ArrayList<String>();
			temp_path.addAll(path);
			paths.add(temp_path);
			return;
		}
		for(int pre_node:pre[node]){
			path.add(word_map[pre_node]);
			print_path(pre,pre_node,path,paths,word_map);
			path.remove(path.size()-1);
		}
		return;
	}
	
	public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {
		String[] word_map = new String[wordList.size()+2];
		List<Integer>[] graph =  BuildGraph(beginWord, endWord, wordList, word_map); 
		
		//dijkstra
		int i,j,distance;
		int[] visited = new int[graph.length];

		int min_distance;
		int[] dis = new int[graph.length];
		ArrayList<Integer>[] pre = new ArrayList[graph.length+2];
		
		for(i = 0; i < pre.length; ++i){
			pre[i] = new ArrayList<Integer>();
		}
		//initialize dis[]
		Iterator graph_it = graph[0].iterator();
		
		while(graph_it.hasNext()){
			dis[(int) graph_it.next()] = 1;
		}
		for(i = 1; i < graph.length; ++i){
			if(dis[i] != 1){
				dis[i] = graph.length;
			}
		}
		i = 0;
		while(i < graph.length){
			int node;
			min_distance = graph.length;
			for(node = 0; node < graph.length; ++ node){
				if(visited[node] == 0 && dis[node] < min_distance){
					min_distance = dis[node];
				}
			}
			for(node = 0; node < graph.length; ++node){
				if(visited[node] == 0 && dis[node] == min_distance){
					visited[node] = 1;
					++i;
					for(Integer next_node:graph[node]){
						int temp_dis = 1 + dis[node];
						if(visited[next_node] == 0 && temp_dis <= dis[next_node]){
							pre[next_node].add(node);
							dis[next_node] = temp_dis;	
						}
					}
				}
			}
		}
		
		List<List<String>> temp_paths = new ArrayList<List<String>>();
		print_paths(pre,word_map,temp_paths);
		Iterator it = temp_paths.iterator();
		
		List<List<String>> paths = new ArrayList<List<String>>();
		while(it.hasNext()){
			List<String> temp_path = (List<String>) it.next();
			String[] for_path = new String[temp_path.size()];
			int temp_node = temp_path.size() - 1;
			for(String node:temp_path){
				for_path[temp_node] = node;
				--temp_node;
			}
			List<String> path = new ArrayList<String>();
			for(String node:for_path){
				path.add(node);
			}
			paths.add(path);
		}

		return paths;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值