微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

212. 单词搜索 II (DFS Trie 删除节点)

 

难度困难

给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。

单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。

 

示例 1:

输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
输出:["eat","oath"]

示例 2:

输入:board = [["a","b"],["c","d"]], words = ["abcb"]
输出:[]
 
struct TrieNode {
    bool is_end;
    string word;
    vector<TrieNode*> children;
    TrieNode() {
        this->is_end = false;
        this->children = vector<TrieNode*>(26);
    }
};

class Solution {
    TrieNode*  root = new TrieNode();
    unordered_set<string> final_set;
    vector<vector<int>> dirs = {{0,1},{0,-1},{1,0},{-1,0}};
public:
    void insert(string word) {
        TrieNode* node = this->root;
        for(auto ch :word) {
            if (node->children[ch-'a'] == nullptr) {
                node->children[ch-'a'] = new TrieNode();
            }
            node = node->children[ch-'a'];
        }
        node->is_end = true;
        node->word = word;
    }
    void deleteWordFromTrie(string word) {
        root = remove(root, word, 0);
    }

    TrieNode* remove(TrieNode* node, string key, int i) {
    if (node == nullptr) {
        return nullptr;
    }
    if (i == key.size()) {
        // 找到了 key 对应的 TrieNode,删除 val
        node->is_end = false;
    } else {
        // 递归去子树进行删除
        node->children[key[i]-'a'] = remove(node->children[key[i]-'a'], key, i + 1);
    }
    // 后序位置,递归路径上的节点可能需要被清理
    if (node->is_end != false) {
        // 如果该 TireNode 存储着 val,不需要被清理
        return node;
    }
    // 检查该 TrieNode 是否还有后缀
    for (int c = 0; c < 26; c++) {
        if (node->children[c] != nullptr) {
            // 只要存在一个子节点(后缀树枝),就不需要被清理
            return node;
        }
    }
    // 既没有存储 val,也没有后缀树枝,则该节点需要被清理
    return nullptr;
}


    void dfs(vector<vector<char>>& board,vector<vector<bool>>& visited, TrieNode* node,string& path, int i, int j) {
        if (i < 0 || j < 0 || i >=board.size() || j >= board[0].size() || visited[i][j]) {
            return;
        }
       
        auto ch = board[i][j];
        if (node == nullptr || node->children[ch-'a'] == nullptr) {
            return;
        }
        path+=ch;
        visited[i][j] = true;
        if (node->children[ch-'a']->is_end) {
            final_set.insert(path);
            deleteWordFromTrie(path);
        }
        for( auto dir :dirs) {
            int new_i = i + dir[0];
            int new_j = j + dir[1];
            dfs(board,visited,node->children[ch-'a'],path,new_i,new_j);                    
        }
        path.pop_back();
        visited[i][j] = false;
    
    }

    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        for(auto word : words) {
            insert(word);
        }
        string path = "";
        vector<vector<bool>> visited = 
        vector<vector<bool>>(board.size(),vector<bool>(board[0].size(),false));
        for (int i = 0; i < board.size();i++) {
            for (int j = 0; j < board[0].size();j++) {
                dfs(board,visited, root,path,i,j);
            }
        }
        vector<string> final_res;
        for(auto w : final_set) {
            final_res.emplace_back(w);
        }
        return final_res;
    }
};

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐