[leetcode]Word Ladder

Word Ladder

Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:

Only one letter can be changed at a time
Each intermediate word must exist in the dictionary
For example,

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

Note:
Return 0 if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.

 这道题是考察图的遍历,一般而言,图的遍历跟树的遍历相似,同样为DFS和BFS,但是DFS因为使用递归,所以对规模较大的数据量比较容易超时,尤其对于这种求层数的题。

该题是典型的求层数类型。考虑使用BFS。感兴趣的可以考虑用DFS,我觉得不用试,肯定超时。

我对图不太熟悉,本以为要构建图的数据结构,后来想了一下,貌似又不用,只需要判断一下是否邻接即可。

第一个版本的代码是酱紫的:

public int ladderLength(String start, String end, Set<String> dict) {
    	Set<String> set = new HashSet<String>(dict);
    	Map<String,Boolean> map = new HashMap<String,Boolean>();
    	set.add(start);
    	set.add(end);
    	for(String s : set){
    		map.put(s, false);
    	}
    	Queue<String> queue = new ArrayDeque<String>();
    	Queue<String> temQ = new ArrayDeque<String>();
    	queue.offer(start);
    	map.put(start, true);
    	int level = 0;
    	while(!queue.isEmpty()){
    		String str = queue.poll();
    		for(String s : set){
    			if(!map.get(s) && match(str, s)){
    				temQ.offer(s);
    				if(s.equals(end)){
    					return level + 2;
    				}
    			}
    		}
    		if(queue.isEmpty()){
    			queue.addAll(temQ);
    			temQ.clear();
    			level++;
    		}
    	}
    	return 0;
    }
    private boolean match(String str1,String str2){
    	int notMatch = 0;
    	for(int i = 0 ; i < str1.length(); i++){
    		if(str1.charAt(i) != str2.charAt(i)){
    			notMatch++;
    			if(notMatch > 1){
    				return false;
    			}
    		}
    	}
    	return true; 
    }

 这里要对遍历过的点进行标记,不熟悉的可以看这里。这里我对是否邻接用了match方法对每一个set集合中的字符串进行判断,但是对于规模较大的数据还是超时了,后来看了其他人的方法,不需要判断集合中的字符串是否match,反过来判断match的字符串是否在集合中。这样对于大规模的集合就可以达到时间优化的目的,但是对于小集合反而多余判断太多。不过好歹也是O(str.length())的时间复杂度,不大。因此就采用了这种方法,代码如下:

 public int ladderLength(String start, String end, Set<String> dict) {
    	Set<String> set = new HashSet<String>(dict);
    	Map<String,Boolean> map = new HashMap<String,Boolean>();
    	set.add(start);
    	set.add(end);
    	for(String s : set){
    		map.put(s, false);
    	}
    	Queue<String> queue = new ArrayDeque<String>();
    	Queue<String> temQ = new ArrayDeque<String>();
    	queue.offer(start);
    	map.put(start, true);
    	int level = 0;
    	while(!queue.isEmpty()){
    		String str = queue.poll();
    		for(int i = 0 ; i < str.length(); i++){
    			for(int j = 0; j < 26; j++){
    				char[] copyStr = str.toCharArray();
    				copyStr[i] =(char) ('a' + j);
    				String s = new String(copyStr);
    				if(set.contains(s) && !map.get(s) ){
    					temQ.offer(s);
    					map.put(s, true);
    					if(end.equals(s)){
    						return level + 2;
    					}
    				}
    			}
    		}
    		if(queue.isEmpty()){
    			queue.addAll(temQ);
    			temQ.clear();
    			level++;
    		}
    	}
    	return 0;
    }

 

 

 

你可能感兴趣的:(LeetCode)