1. 程式人生 > 其它 >【leetcode】212. Word Search II

【leetcode】212. Word Search II

  Given anm x nboardof characters and a list of stringswords, returnall words on the board.Each word must be constructed from letters of sequentially adjacent cells, whereadjacent cellsare horizontally or vertically neighboring. The same letter cell may not be used more than once in a word. 這個題目相比於word search來說不是對一個word進行檢索,而是對多個word 進行檢索,可以對在79題目的基礎上進行修改 ,增加一個迴圈,得到一個基本的解法,但是時間複雜度較高,沒法oc
class Solution {
public:
    bool dfs(vector<vector<char>>& board,string word,int i,int j,int n){
        //遞迴終止條件
        if(n==word.size()) return true;
        if(i<0 || j<0 || i>=board.size()||j>=board[0
].size() || board[i][j]!=word[n]) return false; board[i][j]='0';//這個位置檢索到了 bool flag=(dfs(board,word,i+1,j,n+1) || dfs(board,word,i-1,j,n+1)|| dfs(board,word,i,j+1,n+1)|| dfs(board,word,i,j-1,n+1)); board[i][j]=word[n]; return flag; } vector<string
> findWords(vector<vector<char>>& board, vector<string>& words) { //word search plus版本 word search 是檢索一個word 這個版本是每個word都進行檢索 // 一個單詞一個單詞的去檢索 int m=board.size(),n=board[0].size(); vector<string>res; for(auto word:words){
for(int i=0;i<m;++i){ for(int j=0;j<n;++j){ if(dfs(board,word,i,j,0)){ res.push_back(word); i=m; j=n;//跳出迴圈 } } } } return res; } };
  如何優化這個題目呢,能不能併發的對多個word同時進行檢索呢?通過字典樹來實現快速查詢。
class Solution {
    int dir[5]={1,0,-1,0,1};//檢索方向
public:
    //巢狀類 構建一個字首樹
    class Trie{
        
    public:
        string s;
        Trie *next[26];
        
    public:
        
        Trie() {
            s="";
            memset(next,0,sizeof(next));//初始化多叉樹的索引
            }
  
        void insert(string word){
            Trie *node=this;
            for(auto ww:word){
                if(node->next[ww-'a']==NULL){
                    node->next[ww-'a']=new Trie();
                }
                node=node->next[ww-'a'];
            }
            node->s=word; 
        }
    };
    
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        vector<string> res;
        if(board.size()==0 || board[0].size()==0 || words.size()==0) return res;
        vector<vector<bool>> dp(board.size(),vector<bool>(board[0].size(),false));
        Trie *T=new Trie();
        for(auto word:words){
            T->insert(word);
        }
        for(int i=0;i<board.size();++i){
            for(int j=0;j<board[0].size();++j){
                if(T->next[board[i][j]-'a']!=NULL){
                    search(board,T->next[board[i][j]-'a'],i,j,dp,res);
                }
            }
        }        
        return res;
    }
      void search(vector<vector<char>>& board, Trie* p, int i, int j, vector<vector<bool>>& dp, vector<string>& res) { 
        if (!p->s.empty()) {
            res.push_back(p->s);
            p->s.clear();
        }
        dp[i][j] = true;
        for (int ii=0;ii<4;++ii) {
            int nx = i + dir[ii], ny = j + dir[ii+1];
            if (nx >= 0 && nx < board.size() && ny >= 0 && ny < board[0].size() && !dp[nx][ny] && p->next[board[nx][ny] - 'a']) {
                search(board, p->next[board[nx][ny] - 'a'], nx, ny, dp, res);
            }
        }
        dp[i][j] = false;
    }
};
  同樣也可以用結構體來構建一個字首樹:
class Solution {
public:
    struct TrieNode {
        TrieNode *child[26];
        string str;
    };
    struct Trie {
        TrieNode *root;
        Trie() : root(new TrieNode()) {}
        void insert(string s) {
            TrieNode *p = root;
            for (auto &a : s) {
                int i = a - 'a';
                if (!p->child[i]) p->child[i] = new TrieNode();
                p = p->child[i];
            }
            p->str = s;
        }
    };
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        vector<string> res;
        if (words.empty() || board.empty() || board[0].empty()) return res;
        vector<vector<bool>> visit(board.size(), vector<bool>(board[0].size(), false));
        Trie T;
        for (auto &a : words) T.insert(a);
        for (int i = 0; i < board.size(); ++i) {
            for (int j = 0; j < board[i].size(); ++j) {
                if (T.root->child[board[i][j] - 'a']) {
                    search(board, T.root->child[board[i][j] - 'a'], i, j, visit, res);
                }
            }
        }
        return res;
    }
    void search(vector<vector<char>>& board, TrieNode* p, int i, int j, vector<vector<bool>>& visit, vector<string>& res) { 
        if (!p->str.empty()) {
            res.push_back(p->str);
            p->str.clear();
        }
        int d[][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        visit[i][j] = true;
        for (auto &a : d) {
            int nx = a[0] + i, ny = a[1] + j;
            if (nx >= 0 && nx < board.size() && ny >= 0 && ny < board[0].size() && !visit[nx][ny] && p->child[board[nx][ny] - 'a']) {
                search(board, p->child[board[nx][ny] - 'a'], nx, ny, visit, res);
            }
        }
        visit[i][j] = false;
    }
};