leedcode:212. 单词搜索 II (trie树,dfs,剪枝)

力扣链接:https://leetcode.cn/problems/word-search-ii/description/

思路:

先建立字典树,将单词插入树中,建立ed数组表示cur节点的单词结尾表示的这个单词
建立pass数组表示经过多少次cur节点,初始化cur节点为1

建树后,使用dfs,每次递归后,将之前路径的board[i][j]设置为0,回溯后重置,保证不会重复,经历节点,
再正常对边界进行处理

题解:

const int N = 3e5;
class Solution {
public:
    int cnt;
    int tree[N][26];    
    int pass[N];
    string ed[N];
    vector<string>ans;

    void insert(string s)
    {
        int cur=1;
        pass[cur]++;
        for(int i=0,path;i<s.size();i++)
        {
            path = s[i]-'a';
            if(tree[cur][path]==0)tree[cur][path]=++cnt;
            cur = tree[cur][path];
            pass[cur]++;
        }
        ed[cur]=s;
        
    }

    void build(vector<string>& words)
    {
        cnt=1;
        for(int i=0;i<words.size();i++)
        {
            insert(words[i]);
        }

    }

    int dfs(vector<vector<char>>&board,int i,int j,int cur)
    {
        if(i<0||i>=board.size()||j<0||j>=board[0].size()||board[i][j]==0)return 0;

        char tmp = board[i][j];
        int path = tmp-'a';
        cur = tree[cur][path];
        if(pass[cur]==0)return 0;


        int fix=0;
        if(ed[cur].size()!=0)
        {
            fix++;
            ans.push_back(ed[cur]);
            ed[cur].clear();
        }
        board[i][j]=0;
        fix+=dfs(board,i+1,j,cur);
        fix+=dfs(board,i-1,j,cur);
        fix+=dfs(board,i,j+1,cur);
        fix+=dfs(board,i,j-1,cur);
        pass[cur]-=fix;
        board[i][j]=tmp;
        return fix;


    }

    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        build(words);
        for(int i=0;i<board.size();i++)
        {
            for(int j=0;j<board[0].size();j++)
            {
                dfs(board,i,j,1);
            }
        }
        return ans;

    }
};

posted @ 2025-06-17 18:54  屈臣  阅读(19)  评论(0)    收藏  举报