212. Word Search II (DFS,trie)

来源:互联网 发布:php支付宝sdk集成 编辑:程序博客网 时间:2024/06/08 04:08

题目地址

https://leetcode.com/problems/word-search-ii/

题目描述

Given a 2D board and a list of words from the dictionary, find all words in the board.

Each word must be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.

For example,
Given words = [“oath”,”pea”,”eat”,”rain”] and board =

[  ['o','a','a','n'],  ['e','t','a','e'],  ['i','h','k','r'],  ['i','f','l','v']]

Return [“eat”,”oath”].

求解思路

  • 用纯粹的dfs会超时。

  • 第一次对棋盘构建trie,这是错误的,棋盘可以构建的单词 量显然也是很大的。
    并且这也不符合提议,题目要求的是不同的单词,换句话说words[]里面可能由很多重复的单词,所以应该是对words[] 构建trie,这样可以保证所有不同的单词都在trie中。

  • 在构建好trie之后,采用dfs在元board中查找单词,当该单词是trie中的单词的时候就可即添加到结构集当中。

  • 最后需要利用leetcode的错误检查,去重等处理

ac代码(待优化)

const int N = 26;typedef struct node{    bool isWord;    struct node* next[N];    node(bool m_is = false)    {        isWord = m_is;        for (int i = 0; i < N; i++)        {            next[i] = NULL;        }    }}Trie;vector<vector<char>> mp;int row, col;bool isRightPos(int x, int y){    if (x >= 0 && x < row && y >= 0 && y < col)         return true;    return false;}bool startWithPrefix(Trie* root, string word, int wordLen){    Trie* t = root;    for (int i = 0; i < wordLen; i++)    {        char c = word[i];        if (t == NULL || t->next[c - 'a'] == NULL)            return false;        t = t->next[c - 'a'];    }    return true;}bool searchWordInTrie(Trie* root, string word, int wordLen){    Trie* t = root;    for (int i = 0; i < wordLen; i++)    {        char c = word[i];        if (t == NULL || t->next[c - 'a'] == NULL)            return false;        t = t->next[c - 'a'];    }    return t->isWord;}void insertTrie(Trie* root, string word,int wordLen){    Trie* t = root;    for (int i = 0; i < wordLen; i++)    {        char c = word[i];        if (t->next[c - 'a'] == NULL)            t->next[c - 'a'] = new Trie();        t = t->next[c - 'a'];    }    t->isWord = true;}vector<string> ans;map<string, bool> isHave;class Solution {public:    void dfs(vector<vector<bool>> &vis, string str,int x, int y, Trie* root)    {        if (!isRightPos(x, y) || vis[x][y])            return;        str += mp[x][y];        int strLen = str.size();        if (!startWithPrefix(root, str, strLen))            return;        if (searchWordInTrie(root, str, strLen))        {            //cout << str << endl;            if (isHave[str] == false)            {                ans.push_back(str);                isHave[str] = true;            }        }        int dir[][2] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };        vis[x][y] = true;        for (int i = 0; i < 4; i++)        {            dfs(vis, str, x + dir[i][0], y + dir[i][1], root);        }        vis[x][y] = false;    }    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {        ans.clear(); // 清除数据,leetcode测试有点奇怪        isHave.clear();        mp.clear();        row = board.size();        if (row == 0)            return ans;        col = board[0].size();        if (col == 0)            return ans;        mp = board;        Trie* root = new Trie();        int wordsLen = words.size();        for (int i = 0; i < wordsLen; i++)        {            string word = words[i];            int wordLen = word.size();            insertTrie(root, word, wordLen); // 由单词建立trie树        }        vector<vector<bool>> vis(row, vector<bool>(col));        for (int i = 0; i < row; i++) {            for (int j = 0; j < col; j++) {                dfs(vis, "", i, j, root);            }        }        return ans;    }};

类似题目

矩阵中的路径–79 word Search–DFS回溯
http://blog.csdn.net/qq_26437925/article/details/52166568

0 0