126. 单词接龙 II

链接

题目.

难度:

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]
}

复杂度分析

time

space

执行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值