Golang | Leetcode Golang题解之第126题单词接龙II

发布于:2024-06-03 ⋅ 阅读:(107) ⋅ 点赞:(0)

题目:

题解:

//bfs+dfs(如果是双向bfs,效果会更好)
func findLadders(beginWord string, endWord string, wordList []string) [][]string {
    //字典表(将wordList中的单词放入hash表中,方便查找)
    dict:=make(map[string]bool,0)
    for _,v:=range wordList{
        dict[v]=true
    }
    //如果endWord不在hash表中,表示不存在转换列表,返回空集合
    if !dict[endWord]{
        return [][]string{}
    }
    //将第一个单词放入hash表中,方便实现邻接表(构建图)
    dict[beginWord]=true
    //构建邻接表
    graph:=make(map[string][]string,0)
    //执行bfs搜索,找到每个点到endWord的距离
    distance:=bfs(endWord,dict,graph)
    res:=make([][]string,0)//保存结果
    //执行dfs操作
    dfs(beginWord,endWord,&res,[]string{},distance,graph)
    return res
}

//回溯实现方式一:(个人偏好这个,更符合模板)
func dfs(beginWord string,endWord string,res *[][]string,path []string,distance map[string]int,graph map[string][]string){
    //出递归条件
    if beginWord==endWord{
        path=append(path,beginWord) //加入endWord节点
        tmp:=make([]string,len(path))
        copy(tmp,path)
        (*res)=append((*res),tmp)
        path=path[:len(path)-1] //移除endWord节点
        return
    }
    //否则遍历图
    for _,v:=range graph[beginWord]{
        //遍历图时,朝着距离与终点越来越近的方向进行(当前节点的距离肯定要比下一个距离大1)
        if distance[beginWord]==distance[v]+1{
            path=append(path,beginWord)
            dfs(v,endWord,res,path,distance,graph)
            //回溯(执行完上述的所有时,将其回溯回去)
            path=path[:len(path)-1]
        } 
    }
}
//回溯实现方式二:
func dfs(beginWord string,endWord string,res *[][]string,path []string,distance map[string]int,graph map[string][]string){
    path=append(path,beginWord)
    //出递归条件
    if beginWord==endWord{
        tmp:=make([]string,len(path))
        copy(tmp,path)
        (*res)=append((*res),tmp)
        return
    }
    //否则遍历图
    for _,v:=range graph[beginWord]{
        //遍历图时,朝着距离与终点越来越近的方向进行(当前节点的距离肯定要比下一个距离大1)
        if distance[beginWord]==distance[v]+1{
            dfs(v,endWord,res,path,distance,graph)
        } 
    }
    //回溯(执行完上述的所有时,将其回溯回去)
    path=path[:len(path)-1]
}


//从终点出发,进行bfs,计算每一个点到达终点的距离
func bfs(endWord string,dict map[string]bool,graph map[string][]string)map[string]int{
    distance:=make(map[string]int,0) //每个点到终点的距离
    queue:=make([]string,0)
    queue=append(queue,endWord)
    distance[endWord]=0 //初始值
    for len(queue)!=0{
        cursize:=len(queue)
        for i:=0;i<cursize;i++{
            word:=queue[0]
            queue=queue[1:]
            //找到和word有一位不同的单词列表
            expansion:=expand(word,dict)
            for _,v:=range expansion{
                //构造邻接表
                //我们是从beginWord到endWord构造邻接表,而bfs是从endWord开始,所以构造时,反过来构造
                //即graph[v]=append(graph[v],word)而不是graph[word]=append(graph[word],v)
                graph[v]=append(graph[v],word)
                //表示没访问过
                if _,ok:=distance[v];!ok{
                    distance[v]=distance[word]+1 //距离加一
                    queue=append(queue,v) //入队列
                }
            }
        }
    }
    return distance
}

//获得邻接点
func expand(word string,dict map[string]bool)[]string{
    expansion:=make([]string,0) //保存word的邻接点
    //从word的每一位开始
    chs:=[]rune(word)
    for i:=0;i<len(word);i++{
        tmp:=chs[i] //保存当前位,方便后序进行复位
        for c:='a';c<='z';c++{
            //如果一样则直接跳过,之所以用tmp,是因为chs[i]在变
            if tmp==c{ 
                continue
            }
            chs[i]=c
            newstr:=string(chs)
            //新单词在dict中不存在,则跳过
            if dict[newstr]{
                expansion=append(expansion,newstr)
            }
        }
        chs[i]=tmp //单词位复位
    }
    return expansion
}

网站公告

今日签到

点亮在社区的每一天
去签到