Skip to content

Commit 698fb6f

Browse files
aQuaaQua
authored andcommitted
127 copy fastest
1 parent 7bd7fae commit 698fb6f

File tree

1 file changed

+58
-59
lines changed

1 file changed

+58
-59
lines changed
Lines changed: 58 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,77 @@
11
package Problem0127
22

33
func ladderLength(beginWord string, endWord string, words []string) int {
4+
dictMap := make(map[string]byte)
45

5-
// isTransedEndWord 用于在生成 trans 的过程中标记,存在 ->endWord 的转换关系
6-
// 用于提前结束
7-
isTransedEndWord := false
8-
// cnt 用于记录生成trans的迭代次数
9-
// 其实也是最短路径的长度
10-
res := 1
11-
var bfs func([]string, []string)
12-
// 使用 bfs 方法,递归地生成 trans
13-
bfs = func(words, nodes []string) {
14-
res++
15-
// words 中的 w
16-
// 与 nodes 中的 n ,可以实现 n->w 的转换,
17-
// 则,w 会被放入 newNodes
18-
// 否则,w 会被放入 newWords
19-
newWords := make([]string, 0, len(words))
20-
newNodes := make([]string, 0, len(words))
21-
for _, w := range words {
22-
isTransed := false
23-
for _, n := range nodes {
24-
if isTransable(n, w) {
25-
isTransed = true
6+
for i := 0; i < len(words); i++ {
7+
if _, ok := dictMap[words[i]]; !ok {
8+
dictMap[words[i]] = byte(1)
9+
}
10+
}
2611

27-
}
28-
}
12+
var wq wordQueue
13+
dist := 2
2914

30-
if isTransed {
31-
if w == endWord {
32-
isTransedEndWord = true
33-
return
34-
}
35-
newNodes = append(newNodes, w)
36-
} else {
37-
newWords = append(newWords, w)
15+
addNextWords(beginWord, dictMap, &wq)
16+
for !wq.empty() {
17+
wqLen := wq.size()
18+
for i := 0; i < wqLen; i++ {
19+
word := wq.popNext()
20+
if word == endWord {
21+
return dist
3822
}
39-
}
4023

41-
if len(newWords) == 0 || // words 的所有单词都已经可以从 beginWord trans 到
42-
len(newNodes) == 0 { // newWords 中单词,是 beginWord 无法 trans 到的
43-
return
24+
addNextWords(word, dictMap, &wq)
4425
}
45-
46-
// 上面没有 return,要继续完善 trans
47-
bfs(newWords, newNodes)
26+
dist++
4827
}
4928

50-
// 第一代 nodes 含有且仅含有 beginWord
51-
nodes := []string{beginWord}
52-
bfs(words, nodes)
29+
return 0
30+
}
31+
32+
func addNextWords(beginWord string, dictMap map[string]byte, wq *wordQueue) {
33+
bytes := []byte(beginWord)
34+
delete(dictMap, beginWord)
35+
for i := 0; i < len(bytes); i++ {
36+
diffLetter := bytes[i]
37+
for j := 0; j < 26; j++ {
38+
b := 'a' + byte(j)
39+
if b == diffLetter {
40+
continue
41+
}
5342

54-
if !isTransedEndWord {
55-
// beginWord 无法 trans 到 endWord
56-
return 0
43+
bytes[i] = b
44+
if _, ok := dictMap[string(bytes)]; ok {
45+
wq.push(string(bytes))
46+
delete(dictMap, string(bytes))
47+
}
48+
}
49+
bytes[i] = diffLetter
5750
}
51+
}
5852

59-
return res
53+
type wordQueue struct {
54+
words []string
6055
}
6156

62-
func isTransable(a, b string) bool {
63-
if a == b {
64-
return false
65-
}
66-
// onceAgain == true 说明已经出现过不同的字符了
67-
onceAgain := false
68-
for i := range a {
69-
if a[i] != b[i] {
70-
if onceAgain {
71-
return false
72-
}
73-
onceAgain = true
74-
}
57+
func (wq *wordQueue) empty() bool {
58+
return len(wq.words) == 0
59+
}
60+
61+
func (wq *wordQueue) popNext() string {
62+
if len(wq.words) == 0 {
63+
return ""
7564
}
7665

77-
return true
66+
s := wq.words[0]
67+
wq.words = wq.words[1:]
68+
return s
69+
}
70+
71+
func (wq *wordQueue) push(s string) {
72+
wq.words = append(wq.words, s)
73+
}
74+
75+
func (wq *wordQueue) size() int {
76+
return len(wq.words)
7877
}

0 commit comments

Comments
 (0)