JavaScript中的Word Search II算法

问题描述

我正在尝试为Word Search II问题创建自己的解决方案(请不要向我发送与其他人的解决方案的链接,我正在尝试了解我的代码中的错误)。

问题: 给定2D木板和词典中的单词列表,找到木板中的所有单词。

每个单词必须由顺序相邻的单元格的字母构成,其中“相邻”单元格是水平或垂直相邻的单元格。同一字母单元在一个单词中最多只能使用一次。

示例:

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

Output: ["eat","oath"]

我的解决方案:

var findWords = function(board,words) {
    
    let output = new Set();
    const initials = new Map();
    for(let i=0; i<words.length; i++) {
        let temp;
        if(initials.has(words[i][0]))
            temp = initials.get(words[i][0]);
        else
            temp = [];
        temp.push(words[i]);
        initials.set(words[i][0],temp);
    }
    
    const checkOrder = (row,col,word,tempWord,visited) => {
        if(row < 0 || row >= board.length || col < 0 || col >= board[row].length || board[row][col] !== word[tempWord.length])
            return;
        if(visited[row][col] === 1) return;
        
        tempWord += board[row][col];
        visited[row][col] = 1;
        if(tempWord === word)   output.add(word);            
        
        checkOrder(row,col+1,visited);
        checkOrder(row,col-1,visited);
        checkOrder(row+1,visited);
        checkOrder(row-1,visited);
    }
    
    for(let i=0; i<board.length; i++) {
        for(let j=0; j<board[i].length; j++) {
            if(initials.has(board[i][j])) {
                // might form a word
                const listWords = initials.get(board[i][j]);
                for(let k=0; k<listWords.length; k++) {
                    const visited = new Array(board.length).fill(0).map(() => new Array(board[0].length).fill(0));
                    const word = listWords[k];
                    checkOrder(i,j,"",visited);
                }
            }
        }
    }
    
    return Array.from(output);
};

它对于上面的输入工作正常。但是,对于以下输入:

board: [["a","b","c"],["a","e","d"],"f","g"]]
words: ["abcdefg","gfedcbaaa","eaabcdgfa","befa","dgc","ade"]

我的输出是: ["abcdefg","gfedcbaaa"] 为什么我的代码没有计算工作量:“ eaabcdgfa”?

谢谢

解决方法

在第二个面板中搜索单词eaabcdgfa时,采用深度优先的搜索算法:

  • 从中心的e开始,将其标记为已访问,
  • 在左中角找到一个a,将其标记为已访问,
  • 在左下角找到一个a,将其标记为已访问,
  • 在左下角的b旁边找不到a,因此回溯到第一个a
  • 在左上方找到另一个a,将其标记为已访问,
  • 在木板边缘附近找到bcdgf,将它们全部标记为已访问,
  • 由于已被标记为已访问,因此无法在左下方添加a

问题是,尽管它不是从中心的a到位于中心的e的路由的一部分,但左下角的f被标记为已访问。底部中心。

如果您希望visited数组记录当前对checkOrder的递归调用堆栈已访问的网格正方形,则需要将网格正方形标记为{{ 1}}结束。您可以通过添加行来实现

checkOrder

visited[row][col] = 0; 函数的底部,在对checkOrder的所有递归调用的下方。

我对您的代码进行了更改,发现有checkOrder一词。