1. 程式人生 > >【LeetCode】212. Word Search II 解題報告(C++)

【LeetCode】212. Word Search II 解題報告(C++)

作者: 負雪明燭
id: fuxuemingzhu
個人部落格: http://fuxuemingzhu.cn/


目錄

題目地址: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.

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:

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

題目大意

給定一組座標,找出四個頂點使其能構成長方形,求最小的長方形的面積。注意,邊有可能不和x,y軸平行。

解題方法

字首樹

這個題仍然是字首樹的題目,但是我摳了很久。。果然Hard題就是不好寫啊。

首先,這個題給出的words特別多,但是board的大小反而稍微小了一點,但是題目沒有提示,這就造成了在board中搜索每個單詞的方法會超時。正確的做法應該是,直接對board進行搜尋,判斷搜尋過程中能不能構成words中的某個字串。

如果我們儲存路徑,再去word中查,這個效率就很低了,這裡對字首樹進行了改變,對於單詞節點不去儲存isWord,而是儲存現在位置的字串是什麼,那麼在board搜尋過程中,如果恰好找到了一個字首樹中的單詞,那就放到結果裡。

這個題我一直在錯,卻想不明白的地方是在找到一個單詞之後對p->str進行了清空的同時,return了!這是錯誤的!因為對於相同字首的字串,我們還要繼續向後搜尋的。比如"anes","anesis"

如果在第一個單詞搜尋到之後return,就不可能搜尋到第二個單詞。所以不能return.

另外,返回的結果排不排序不影響,對時間影響不大。

當代碼比較長的時候,一定要保證寫出的每個模組是對的,只有這樣才能減少檢查的時間。特別是細節錯誤,千萬不能犯。

python程式碼如下:

class TrieNode {
public:
    vector<TrieNode*> child;
    string str;
    TrieNode() : child(26, nullptr), str("") {};
    ~TrieNode() {
        for (auto c : child) delete c;
    }
};
class Trie {
public:
    TrieNode* root;
    Trie() : root(new TrieNode()){};
    void insert(string word) {
        TrieNode* p = root;
        for (char c : word) {
            int i = c - 'a';
            if (!p->child[i])
                p->child[i] = new TrieNode();
            p = p->child[i];
        }
        p->str = word;
    }
};
class Solution {
public:
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        const int M = board.size(), N = board[0].size();
        vector<vector<bool>> visited(M, vector<bool>(N, false));
        Trie trie;
        for (string word : words)
            trie.insert(word);
        vector<string> res;
        for (int r = 0; r < M; r ++) {
            for (int c = 0; c < N; c++) {
                if (trie.root->child[board[r][c] - 'a']) {
                    helper(board, trie.root->child[board[r][c] - 'a'], r, c, visited, res);
                }
            }
        }
        sort(res.begin(), res.end());
        return res;
    }
    void helper(vector<vector<char>>& board, TrieNode* p, int r, int c, vector<vector<bool>>& visited, vector<string>& res) {
        const int M = board.size(), N = board[0].size();
        if (!p->str.empty()){
            res.push_back(p->str);
            p->str.clear();
        }
        visited[r][c] = true;
        for (auto d : dirs) {
            int nx = r + d.first;
            int ny = c + d.second;
            if (nx < 0 || nx >= M || ny < 0 || ny >= N || visited[nx][ny] || !p->child[board[nx][ny] - 'a'])
                continue;
            helper(board, p->child[board[nx][ny] - 'a'], nx, ny, visited, res);
        }
        visited[r][c] = false;
    }

private:
    vector<pair<int, int>> dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
};

日期

2018 年 12 月 23 日 —— 周賽成績新高