深度优先搜索(DFS)和广度优先搜索(BFS)

今天 leetcode 写了一道题,它既可以用深度优先搜索,也可以用广度优先搜索来解决,不妨一起来看看吧!



题目描述

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

image.png

示例:

输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number

下面,我们将分别使用 DFS 和 BFS 来解决该问题。

深度优先搜索(DFS)

Depth-First-Search:深度优先搜索,它沿着树的深度遍历树的节点,尽可能深的搜索树的分 支。当节点的所有边都己被访问过,搜索将回溯到原节点边的起始节点。这一过程一直进行到已发现从原节点可达的所有节点为止。如果存在未被访问的节点,则选择其中一个作为节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
打个不恰当的比方,你开车去一个地方,但是路上分叉路多,你又没地图,那只能把每个分叉路走都走一遍,走到头也没到,返回之前路口再走,最多把所有的子路径都走一遍就能到达目的地。

下面,我们来看看如何利用 DFS 来解决这个问题。
以一个例子来看,"237"。
这是一个示意图,用画布画的,有些丑。。。


image.png

简单模拟下这个过程
先从 '2' 的一个节点 a 出发,发现还能往下走,就来到了 '3' 的一个节点 d ,发现还可以继续往下走,就来到了 '7' 的一个节点 p,这个时候再往下走就不行了,此时我们把 "adp" 存起来。


image.png

由于已经无路可走了,只能返回之前的节点,再往下走,来到 q ,再往下走,无路可走了,把 "adq" 存起来。


image.png

重复上面的过程。
那么终止条件是什么呢?当然是"层数"了
图示过程:


image.png

程序如下:

class Solution {
public:
    vector res;
    unordered_map store;
    vector letterCombinations(string digits) {
        if(digits.empty()){
            return res;
        }
        store = {
            {'2',"abc"}, {'3',"def"}, {'4',"ghi"}, {'5',"jkl"}, {'6',"mno"}, {'7',"pqrs"}, {'8',"tuv"}              , {'9',"wxyz"}};
        dfs("", 0,digits);
        return res;
    }
    void dfs(string str,int index,string digits){
        int len=digits.size();
        if(len==index){
            res.push_back(str);
            return ;
        }
        string targerStr=store[digits[index]];
        for(auto temp : targerStr){
            dfs(str+temp,index+1,digits);
        }
        return ;
    }
};

广度优先搜索(BFS)

BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。如果所有节点均被访问,则算法中止。
简单模拟下这个过程:
先把根节点入队列:


image.png

再找下一个未被访问的节点:


image.png

当然我们不能简单地把 "def" “塞进去”,"def" 进去后的结果应该是其与队列中所有成员的组合。
这个过程可以这样操作:
队列中所有元素都分别加上当前节点的所有元素。


image.png

之后重复这样的操作:


image.png

程序如下:

class Solution {
public:
    vector res;
    unordered_map store;
    vector letterCombinations(string digits) {
        if(digits.empty()){
            return res;
        }
        store = {{'2',"abc"}, {'3',"def"}, {'4',"ghi"}, {'5',"jkl"}, {'6',"mno"},{'7',"pqrs"}, {'8',"tuv"}, {'9',"wxyz"}};
        queue q;
        q.push("");
        for(auto temp : digits){
            string targetStr=store[temp];
            int qSize=q.size();
            //位于当前层,添加字符
            for(int i=0;i

这个题使用深度优先搜索(DFS)和广度优先搜索(BFS)都可以解决,下面我们汇总两个程序。

汇总

把这个两个程序汇总,更方便我们测试,整理如下:

#include 
using namespace std;

class DFS_{
public:
    vector res;
    string digits;
    unordered_map store;
    vector letterCombinations(){
        this->digits = digits;
        if (digits.empty()){
            return res;
        }
        store = unordered_map{{'2', "abc"}, {'3', "def"}, {'4', "ghi"}, {'5', "jkl"}, {'6', "mno"}, {'7', "pqrs"}, {'8', "tuv"}, {'9', "wxyz"}};
        dfs("", 0);
        return res;
    }

    void dfs(string resultStr, int index){
        int digitsSize = this->digits.size();
        if (digitsSize == index){
            res.push_back(resultStr);
            return ;
        }
        string targetStr = store[this->digits[index]];
        for (auto tmpChar : targetStr){
            dfs(resultStr + tmpChar, index + 1);
        }
        return ;
    }
};
class BFS_{
public:
    vector res;
    string digits;
    unordered_map store;
    vector letterCombinations(){
        this->digits = digits;
        if(digits.empty()){
            return res;
        }
        store = {{'2',"abc"}, {'3',"def"}, {'4',"ghi"}, {'5',"jkl"}, {'6',"mno"},{'7',"pqrs"}, {'8',"tuv"}, {'9',"wxyz"}};
        queue q;
        q.push("");
        for(auto temp : digits){
            string targetStr=store[temp];
            int qSize=q.size();
            //位于当前层,添加字符
            for(int i=0;i>str;
    DFS_ d;
    BFS_ b;
    d.digits=str;
    b.digits=str;
    vector res_d = d.letterCombinations();
    cout<<"DFS: "< res_b = b.letterCombinations();
    for(auto& temp : res_b){
        cout<

示例如下:


image.png

虽然 DFS 和 BFS 的理论不难理解,实际应用过程中还是需要多加练习,才能很好地掌握。

你可能感兴趣的:(深度优先搜索(DFS)和广度优先搜索(BFS))