You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Word Hunt游戏DFS算法无法找到最优解的技术问题排查

Word Hunt DFS算法问题排查与优化方案

问题排查

  1. 输出顺序逻辑错误:你在获取按长度降序排列的单词列表后调用了longest_words.reverse(),导致输出顺序变为从短到长,所以前100个结果全是短单词,这是代码逻辑失误,并非算法找不到长单词。
  2. DFS路径复制效率低下:每次递归都复制path集合,带来大量不必要的内存开销和时间消耗,对于较长的单词路径,可能因性能问题无法完成遍历,进而遗漏长单词。
  3. 无前缀剪枝:当前DFS会遍历所有可能的字母组合,即使当前前缀不在任何有效单词的开头,这会浪费大量时间在无效路径上,降低算法效率,甚至可能错过长单词的遍历。
  4. 单词列表验证缺失:需确认目标长单词(如adulterations、unforgivingness)是否存在于你的单词列表中,若词库未包含这些单词,算法自然无法识别。

优化方案

1. 修复输出顺序

移除longest_words.reverse()调用,直接输出按长度降序排列的结果,最长单词会优先显示。

2. 优化DFS回溯方式

将路径复制改为原地修改+回溯,避免每次递归复制集合,大幅提升效率:

  • 递归前将当前坐标加入path
  • 递归完成后从path中移除该坐标
  • 直接传递原path引用,无需复制

3. 实现前缀树(Trie)进行剪枝

将单词列表转换为前缀树,在DFS过程中实时检查当前前缀是否存在于Trie中:

  • 如果当前前缀不是任何单词的前缀,直接终止该分支的递归
  • 如果当前前缀是有效单词,加入结果集合
  • 这种剪枝能减少90%以上的无效递归,显著提升遍历速度,确保找到所有可能的长单词

修改后的完整代码

import os
import time

class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_end_of_word = False

class Trie:
    def __init__(self):
        self.root = TrieNode()
    
    def insert(self, word):
        node = self.root
        for char in word:
            if char not in node.children:
                node.children[char] = TrieNode()
            node = node.children[char]
        node.is_end_of_word = True
    
    def search(self, word):
        node = self.root
        for char in word:
            if char not in node.children:
                return False
            node = node.children[char]
        return node.is_end_of_word

def read_grid():
    grid = []
    for i in range(4):
        row = input(f"Enter row {i+1} (4 letters): ").strip().lower()
        if len(row) != 4 or not row.isalpha():
            raise ValueError("Each row must contain exactly 4 letters.")
        grid.append(list(row))
    return grid

def read_word_list(file_path):
    file_path = os.path.expanduser("~/Self Projects/Word Hunt/word_list.txt")
    trie = Trie()
    word_set = set()
    with open(file_path, 'r') as file:
        for line in file:
            word = line.strip().lower()
            if len(word) >=3:
                trie.insert(word)
                word_set.add(word)
    return trie, word_set

def find_words(grid, trie, word_set):
    directions = [(-1, -1), (-1, 0), (-1, 1),
                  (0, -1),          (0, 1),
                  (1, -1),  (1, 0), (1, 1)]
    found_words = set()
    rows, cols = len(grid), len(grid[0])
    
    def dfs(x, y, path, current_word, node):
        if not (0 <= x < rows and 0 <= y < cols):
            return
        if (x, y) in path:
            return
        
        char = grid[x][y]
        if char not in node.children:
            return  # 前缀不存在,剪枝
        
        current_word += char
        current_node = node.children[char]
        
        # 如果当前是有效单词,加入结果
        if current_node.is_end_of_word and current_word in word_set:
            found_words.add(current_word)
        
        # 回溯:加入路径
        path.add((x, y))
        for dx, dy in directions:
            dfs(x + dx, y + dy, path, current_word, current_node)
        # 回溯:移除路径
        path.remove((x, y))
    
    for i in range(rows):
        for j in range(cols):
            dfs(i, j, set(), "", trie.root)
    
    return found_words

def word_hunt_solver(grid, trie, word_set):
    possible_words = find_words(grid, trie, word_set)
    # 按长度降序,长度相同按字母顺序升序排列
    sorted_words = sorted(possible_words, key=lambda word: (-len(word), word))
    return sorted_words[:100]

if __name__ == "__main__":
    grid = read_grid()
    
    start_time = time.time()
    
    trie, word_set = read_word_list('word_list.txt')
    longest_words = word_hunt_solver(grid, trie, word_set)
    
    # 直接输出最长的单词在前
    for word in longest_words:
        print(word)
    
    print(f"\nProgram Execution Time: {time.time() - start_time:.4f} seconds")

优化说明

  1. 前缀树剪枝:通过Trie节点遍历实现前缀检查,避免无效路径遍历,大幅提升效率。
  2. 回溯优化:采用原地修改路径的回溯方式,减少内存消耗和时间开销。
  3. 输出逻辑修复:移除反转操作,直接输出按长度降序的结果,确保最长单词优先显示。
  4. 单词集合验证:保留单词集合用于快速验证完整单词,避免Trie遍历的额外开销。

额外建议

  • 检查你的单词列表,确认adulterations、unforgivingness等目标单词是否存在,若不存在需补充词库。
  • 4x4网格的最长单词长度为16,优化后的算法能高效遍历所有可能的长路径,确保不会遗漏有效单词。

内容的提问来源于stack exchange,提问作者Siddd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:34:54