public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
		Set<String> beginSet = new HashSet<String>();
		Set<String> endSet = new HashSet<String>();
		
		int len = 1;
		HashSet<String> visited = new HashSet<String>();
		
		beginSet.add(beginWord);
		endSet.add(endWord);
		
		while (!beginSet.isEmpty() && !endSet.isEmpty()) {
			if (beginSet.size() > endSet.size()) {
				Set<String> set = beginSet;
				beginSet = endSet;
				endSet = set;
			}
			
			Set<String> temp = new HashSet<String>();
			// loop all the words in beginSet and find possible mutations
			for (String word : beginSet) {
				char[] chars = word.toCharArray();
				
				// mutate each character
				for (int i = 0; i < chars.length; i++) {
					// mutate the character from a to z
					for (char c = 'a'; c <= 'z'; c++) {
						char original = chars[i]; // we need to change back to original
						chars[i] = c;
						String target = String.valueOf(chars);
						
						if (endSet.contains(target)) {
							return len + 1;
						}
						
						if (!visited.contains(target) && wordList.contains(target)) {
							temp.add(target);
							visited.add(target);
						}
						chars[i] = original;
					}
					
				}
			}
			
			beginSet = temp;
			len++;
		}
		
		return 0;
	}