详细见:leetcode.com/problems/word-ladder
Java Solution: github
package leetcode;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
/*
* Given two words (beginWord and endWord), and a dictionary's word list,
* find the length of shortest transformation sequence
* from beginWord to endWord, such that:
Only one letter can be changed at a time
Each intermediate word must exist in the word list
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["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.
*/
import java.util.Set;
public class P127_WordLadder {
/*
* 184 ms
* 6.20%
*/
static class Solution_Answer {
long count = 0;
long count_replace = 0;
public int ladderLength(String start, String end, Set<String> dict) {
if (dict == null) {
return 0;
}
if (start.equals(end)) {
return 1;
}
dict.add(start);
dict.add(end);
HashSet<String> hash = new HashSet<String>();
Queue<String> queue = new LinkedList<String>();
queue.offer(start);
hash.add(start);
int length = 1;
while(!queue.isEmpty()) {
length++;
int size = queue.size();
for (int i = 0; i < size; i++) {
String word = queue.poll();
for (String nextWord: getNextWords(word, dict)) {
if (hash.contains(nextWord)) {
continue;
}
if (nextWord.equals(end)) {
System.out.println("count : " + count);
System.out.println("count_replace : " + count_replace);
return length;
}
count ++;
hash.add(nextWord);
queue.offer(nextWord);
}
}
}
return 0;
}
// replace character of a string at given index to a given character
// return a new string
private String replace(String s, int index, char c) {
char[] chars = s.toCharArray();
chars[index] = c;
count_replace ++;
return new String(chars);
}
// get connections with given word.
// for example, given word = 'hot', dict = {'hot', 'hit', 'hog'}
// it will return ['hit', 'hog']
private ArrayList<String> getNextWords(String word, Set<String> dict) {
ArrayList<String> nextWords = new ArrayList<String>();
for (char c = 'a'; c <= 'z'; c++) {
for (int i = 0; i < word.length(); i++) {
if (c == word.charAt(i)) {
continue;
}
String nextWord = replace(word, i, c);
if (dict.contains(nextWord)) {
nextWords.add(nextWord);
}
}
}
return nextWords;
}
}
}
C Solution: github
#pragma warning(disable:4786)
#pragma warning(disable:4503)
/*
url: leetcode.com/problems/word-ladder
need to use advanced data structure
choose cpp
AC 323ms 29.09%
*/
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <set>
using namespace std;
int ladderLength(string s, string t, vector<string >& w) {
int sn = s.size() , i;
set<string > nv , hv;
for (i = 0; i < w.size(); i ++) nv.insert(w[i]);
map<string, vector<string > > m;
queue<string > q;
nv.insert(s);
q.push(s);
bool isFind = false;
int ans = 2;
while (! q.empty()) {
int size = q.size();
while (size -- > 0) {
string n = q.front();
string v = n;
q.pop();
for (i = 0; i < sn; i ++) {
for (char c = 'a'; c <= 'z'; c ++) {
v[i] = c;
if (! nv.count(v)) continue;
if (! hv.count(v)) {
hv.insert(v);
q.push(v);
}
m[v].push_back(n);
if (! v.compare(t)) isFind = true;
}
v[i] = n[i];
}
}
if (isFind) break;
ans ++;
for (set<string >::iterator iter = hv.begin(); iter != hv.end(); iter ++)
nv.erase(*iter);
hv.clear();
}
return isFind ? ans : 0;;
}
int main() {
string g[] = {"hot","dot","dog","lot","log","cog"};
string s = "hit", t = "cog";
vector<string > w;
int i;
for (i = 0; i < (sizeof(g)/sizeof(g[0])); i ++) w.push_back(g[i]);
int ans = ladderLength(s, t, w);
cout<<ans<<endl;
return 0;
}
Python Solution: github
#coding=utf-8
'''
url: leetcode.com/problems/word-ladder
@author: zxwtry
@email: zxwtry@qq.com
@date: 2017年5月12日
@details: Solution: 902ms 44.52%
'''
from jinja2._compat import unichr
class Solution(object):
def ladderLength(self, b, e, w):
"""
:type b: str
:type e: str
:type w: List[str]
:rtype: int
"""
nv = set(w)
hv = set()
sn = len(b)
q = []
nv.add(b)
q.append(b)
isFind = False
count = 2
while True:
l = len(q)
if l == 0: break
while l > 0:
l -= 1
s = q[0]
q.remove(q[0])
cs = [s[i] for i in range(sn)]
for i in range(sn):
for j in range(26):
cs[i] = unichr(97+j)
ns = "".join(cs)
if not ns in nv: continue
if not ns in hv:
hv.add(ns)
q.append(ns)
if ns == e: isFind = True
cs[i] = s[i]
if isFind: break
count += 1
for v in hv: nv.remove(v)
hv.clear()
return 0 if not isFind else count
if __name__ == "__main__":
b, e = "hit", "cog"
w = ["hot","dot","hog","dog","lot","log","cog"]
# b, e = "a", "c"
# w = ["a", "b", "c"]
print(Solution().ladderLength(b, e, w))