Leetcode 212. 单词搜索 II C++

Leetcode 212. 单词搜索 II

题目

给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。

示例:

输入: 
words = ["oath","pea","eat","rain"] and board =
[
  ['o','a','a','n'],
  ['e','t','a','e'],
  ['i','h','k','r'],
  ['i','f','l','v']
]

输出: ["eat","oath"]
说明:
你可以假设所有输入都由小写字母 a-z 组成。

题解

字典树+dfs回溯
对字典words构建字典树,之后我们在网格中的每一点作为起点进行深搜回溯。需要注意的一点是,如果单词找到后,需要在字典树中把标记去掉,以防重复搜索。详细过程见代码

代码

struct Node{
    bool word;
    string str;
    unordered_map<char,Node*> next;
};
class Trim{
public:
    Node* root;
    Trim(){
        root = new Node();
    }
    void insert(string& word){
        int len = word.length();
        Node* now = root;
        for(int i=0; i<len; i++){
            if(now->next.count(word[i]) == 0){
                Node* node = new Node();
                now->next[word[i]] = node;
            }
            now = now->next[word[i]];
        }
        now->word = true;
        now->str = word;
    }
    void play(vector<vector<char>>& board,vector<string>& ans){
        int m=board.size(),n=board[0].size();
        for(int i=0; i<m; i++){			//每个网格作为起点
            for(int j=0; j<n; j++){
                search(i,j,m,n,root,board,ans);
            }
        }
    }
    void search(int i,int j,int m,int n,Node* now,vector<vector<char>>& board,vector<string>& ans){
        if(now->word){
            now->word = false;		//表明该单词已经搜到了
            ans.push_back(now->str);
        }
        if(i<0 || i>m-1 || j<0 || j>n-1)  return;
        if(now->next.count(board[i][j]) != 0){
            char cur = board[i][j];
            board[i][j] = '#';		//表明该方格的单词已经被使用过
            search(i+1,j,m,n,now->next[cur],board,ans);
            search(i-1,j,m,n,now->next[cur],board,ans);
            search(i,j+1,m,n,now->next[cur],board,ans);
            search(i,j-1,m,n,now->next[cur],board,ans);
            board[i][j] = cur;		//回溯
        }
        
    }
};
class Solution {
public:
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        Trim trim;
        int n = words.size();
        for(int i=0; i<n; i++){		//构建字典树
            trim.insert(words[i]);
        }
        vector<string> ans;
        trim.play(board,ans);
        return ans;
    }
};

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-search-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

你可能感兴趣的:(Leetcode 212. 单词搜索 II C++)