链接
题目.
难度:
high
解答:
这其实就是图的算法,Dijkstra算法
这道题,先求直达的最小路径,这个用bfs没啥好说的,一般求路径的问题就是要用dfs,可是不需要求所有的到达路径,也不需要求随意的一条到达路径,不然dfs准没错。所以我们还是要用bfs,不过在bfs的时候,把经过的所有节点都求出从开始到他这儿的路径,看起来好像很浪费空间,不过就这样做确实可以达到目的,不然重构路径确实很困难。
另外还有说spfa算法,太复杂了不玩了
func transferSteps(w1, w2 string) int {
steps := 0
for i := 0; i < len(w1); i++ {
if w1[i] != w2[i] {
steps++
}
}
return steps
}
func findLadders(beginWord string, endWord string, wordList []string) [][]string {
validBegin, validEnd := false, false
wordMap := make(map[string]struct{}, len(wordList)+1)
for _, v := range wordList {
if v == endWord {
validEnd = true
}
if transferSteps(v, beginWord) <= 1 {
validBegin = true
}
wordMap[v] = struct{}{}
}
if !validBegin || !validEnd {
return nil
}
if _, ok := wordMap[beginWord]; !ok {
wordMap[beginWord] = struct{}{}
wordList = append(wordList, beginWord)
}
oneStepMap := make(map[string][]string, len(wordMap))
for v := range wordMap {
oneStepMap[v] = make([]string, 0)
}
for i := 0; i < len(wordList)-1; i++ {
for j := i + 1; j < len(wordList); j++ {
if transferSteps(wordList[i], wordList[j]) == 1 {
oneStepMap[wordList[i]] = append(oneStepMap[wordList[i]], wordList[j])
oneStepMap[wordList[j]] = append(oneStepMap[wordList[j]], wordList[i])
}
}
}
//fmt.Println("neighbours", oneStepMap)
visitPaths := make(map[string][][]string) //all paths to this node
for v := range oneStepMap {
visitPaths[v] = make([][]string, 0)
}
visitPaths[beginWord] = [][]string{{beginWord}}
prevVisited := make(map[string]struct{})
prevVisited[beginWord] = struct{}{}
currentChoices := []string{beginWord}
breakFlag := false
for len(currentChoices) > 0 {
//fmt.Println("current:", currentChoices)
for _, v := range currentChoices {
prevVisited[v] = struct{}{}
}
nextChoicesMap := make(map[string]struct{})
for _, v1 := range currentChoices {
for _, v2 := range oneStepMap[v1] {
//fmt.Println("checking", v1, v2)
if _, ok := prevVisited[v2]; !ok {
for _, v := range visitPaths[v1] {
tmp := make([]string, len(v))
copy(tmp, v)
tmp = append(tmp, v2)
visitPaths[v2] = append(visitPaths[v2], tmp)
}
if v2 == endWord {
breakFlag = true
}
nextChoicesMap[v2] = struct{}{}
}
}
}
//fmt.Println("next:", nextChoicesMap)
if breakFlag {
break
} else {
currentChoices = currentChoices[0:0]
for v := range nextChoicesMap {
currentChoices = append(currentChoices, v)
}
}
}
//fmt.Println("visited", visitPaths)
return visitPaths[endWord]
}