[leetcode] wordSearchII

个人认为实现了一个比较完备的Trie树,可以增添、删除,高内聚,低耦合。

class TrieNode{
private:
    #define CHARACTER_NUM 26
    TrieNode * next[CHARACTER_NUM];
    int cnt[CHARACTER_NUM];
    bool trail;
public:
    TrieNode(){
        fill(next, next + CHARACTER_NUM, (TrieNode *)NULL);
        fill(cnt, cnt + CHARACTER_NUM, 0);
        trail = false;
    }

    TrieNode * insert(char c){
        unsigned int idx = c -'a';
        if(this->next[idx] == NULL){
            this->next[idx] = new TrieNode();
        }
        this -> cnt[idx]++;
        return this->next[idx];
    }

    TrieNode * remove(char c){
        unsigned int idx = c - 'a';
        this -> cnt[idx]--;
        return this->next[idx];
    }

    bool isTrail(){
        return this->trail;
    }

    bool del(char c){
        unsigned int idx = c - 'a';
        if(this->next[idx] && this -> cnt[idx] == 0){
            delete this->next[idx];
            this->next[idx] = NULL;
            return true;
        }
        return false;
    }

    void setTrail(bool set){
        this->trail = set;
    }

    TrieNode * search(char c){
        unsigned int idx = c - 'a';
        return this->next[idx];
    }
};

class Trie{
public:
    enum type {invalid = 0, prefix, item};

    Trie(){
        root = new TrieNode();
    }

    void insert(string &word){
        TrieNode * ptr = root;
        for(auto c : word){
            ptr = ptr->insert(c);
        }
        ptr -> setTrail(true);
    }

    type search(string &word){
        TrieNode * ptr = root;
        for(auto c : word){
            ptr = ptr->search(c);
            if(ptr == NULL) return invalid;
        }

        if(ptr->isTrail()) return item;
        return prefix;
    }


    void remove(string &word){
        TrieNode * ptr = root;
        stack<TrieNode*> st;
        st.push(ptr);
        for(auto c : word){
            ptr = ptr->remove(c);
            if(ptr == NULL) return;
            st.push(ptr);
        }

        //ptr = st.top();
        ptr -> setTrail(false);
        st.pop();

        for(int i = word.length() - 1; i >= 0; i--){
            ptr = st.top();
            st.pop();
            if(ptr -> del(word[i]) == false) return;
        }
    }

    ~Trie(){
        delete root;
    }

private:
    TrieNode * root;
};

class Solution {
public:
    Trie trie;
    vector<string> ret;

    void search(vector<vector<bool>> &visit, vector<vector<char>> &board, int x, int y, string str){
        if(x < 0 || x >= board.size() || y < 0 || y >= board[0].size() || visit[x][y]) return;

        str.push_back(board[x][y]);
        if(trie.search(str) == Trie::invalid) return;

        if(trie.search(str) == Trie::item){
            ret.push_back(str);
            trie.remove(str);
        }

        visit[x][y] = true;
        search(visit, board, x - 1, y, str);
        search(visit, board, x + 1, y, str);
        search(visit, board, x, y - 1, str);
        search(visit, board, x, y + 1, str);
        visit[x][y] = false;
    }

    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        vector<vector<bool>> visit(board.size(), vector<bool>(board[0].size(), false));
        for(int i = 0; i < words.size(); i++){
            if(trie.search(words[i]) != Trie::item)
                trie.insert(words[i]);
        }

        for(int i = 0; i <= board.size(); i++){
            for(int j = 0; j <= board.size(); j++){
                search(visit, board, i, j, string(""));
            }
        }
        return ret;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值