zoukankan      html  css  js  c++  java
  • 212. 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.

    Example:

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

    Note:
    You may assume that all inputs are consist of lowercase letters a-z.

     
    Approach #1: Trie + DFS. [C++] 
    class Trie{
    public:
        Trie *children[26];         // pointer to its substring starting with 'a' to 'z'
        bool leaf;      // if the node is a leaf, or if there is a word stopping at here
        int idx;        // if it is a leaf, the string index of the array words
        Trie() {
            this->leaf = false;
            this->idx = 0;
            fill_n(this->children, 26, nullptr);
        }
    };
    
    
    class Solution {
    public:
        void insertWords(Trie *root, vector<string>& words, int idx) {
            int pos = 0, len = words[idx].size();
            while(pos < len) {
                if (nullptr == root->children[words[idx][pos]-'a'])
                    root->children[words[idx][pos]-'a'] = new Trie();
                root = root->children[words[idx][pos++]-'a'];
            }
            root->leaf = true;
            root->idx = idx;
        }
        
        Trie *buildTrie(vector<string>& words) {
            Trie *root = new Trie();
            int i;
            for (i = 0; i < words.size(); ++i)
                insertWords(root, words, i);
            return root;
        }
        
        void checkWords(vector<vector<char>>& board, int i, int j, int row, 
                        int col, Trie *root, vector<string>& res, vector<string>& words) {
            char temp;
            if (board[i][j] == 'X') return ;        // visited before;
            if (nullptr == root->children[board[i][j]-'a']) return;     // no string with such prefix;
            else {
                temp = board[i][j];
                if (root->children[temp-'a']->leaf) {       // if it is a leaf
                    res.push_back(words[root->children[temp-'a']->idx]);
                    root->children[temp-'a']->leaf = false;     // set to false to indicate that we found it already
                }
                board[i][j] = 'X';      // mark the current position as visited
                // check all the possible neighbors
                if (i > 0) checkWords(board, i - 1, j, row, col, root->children[temp-'a'], res, words);
                if ((i+1) < row) checkWords(board, i + 1, j, row, col, root->children[temp-'a'], res, words);
                if (j > 0) checkWords(board, i, j - 1, row, col, root->children[temp-'a'], res, words);
                if ((j+1) < col) checkWords(board, i, j + 1, row, col, root->children[temp-'a'], res, words);
                board[i][j] = temp;
            }
        }
        
        vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
            vector<string> res;
            int row = board.size();
            if (0 == row) return res;
            int col = board[0].size();
            if (0 == col) return res;
            int wordCount = words.size();
            if (0 == wordCount) return res;
            
            Trie *root = buildTrie(words);
            
            int i, j;
            for (i = 0; i < row; ++i) {
                for (j = 0; j < col && wordCount > res.size(); ++j) {
                    checkWords(board, i, j, row, col, root, res, words);
                }
            }
            return res;
        }
    };
    

      

    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    猴子得到一堆桃,当天吃了一半之后,又多吃了1个。以后每天,猴子都吃了剩余的一半桃子之>后,又多吃一个。在第10天,只剩下1个桃子。输出这堆桃最初有多少个。
    打印9 9乘法表
    尝试实现一个管理系统, 名字和电话号分别用两个列表存储 =======通讯录管理系统======= 1.增加姓名和手机 2.删除姓名 3.修改手机 4.查询所有用户 5.根据姓名查找手机号 6.退出
    求结果
    背景流动
    1
    zuoye
    假期 作业1220
    python1217作业
    pythonzuoye20181212
  • 原文地址:https://www.cnblogs.com/h-hkai/p/10349498.html
Copyright © 2011-2022 走看看