zoukankan      html  css  js  c++  java
  • Leetcode 212.单词搜索II

    单词搜索II

    给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词。

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

    示例:

    输入:

    words = ["oath","pea","eat","rain"] and board =

    [

    ['o','a','a','n'],

    ['e','t','a','e'],

    ['i','h','k','r'],

    ['i','f','l','v']

    ]

    输出: ["eat","oath"]

    说明:
    你可以假设所有输入都由小写字母 a-z 组成。

    提示:

    • 你需要优化回溯算法以通过更大数据量的测试。你能否早点停止回溯?
    • 如果当前单词不存在于所有单词的前缀中,则可以立即停止回溯。什么样的数据结构可以有效地执行这样的操作?散列表是否可行?为什么? 前缀树如何?如果你想学习如何实现一个基本的前缀树,请先查看这个问题: 实现Trie(前缀树)

    方法:前缀树+深度优先搜索。

     

     1 import java.util.ArrayList;
     2 import java.util.HashSet;
     3 import java.util.List;
     4 import java.util.Set;
     5 
     6 public class Solution {
     7     private TrieNode root = new TrieNode();
     8     private int[] ro = {-1, 1, 0, 0};
     9     private int[] co = {0, 0, -1, 1};
    10     private void find(char[][] board, boolean[][] visited, int row, int col, TrieNode node, Set<String> founded) {
    11         visited[row][col] = true;
    12         TrieNode current = node.nexts[board[row][col]-'a'];
    13         if (current.word != null) founded.add(current.word);
    14         for(int i=0; i<4; i++) {
    15             int nr = row + ro[i];
    16             int nc = col + co[i];
    17             if (nr < 0 || nr >= board.length || nc < 0 || nc >= board[nr].length || visited[nr][nc]) continue;
    18             TrieNode next = current.nexts[board[nr][nc]-'a'];
    19             if (next != null) find(board, visited, nr, nc, current, founded);
    20         }
    21         visited[row][col] = false;
    22     }
    23     public List<String> findWords(char[][] board, String[] words) {
    24         Set<String> founded = new HashSet<>();
    25         for(int i=0; i<words.length; i++) {
    26             char[] wa = words[i].toCharArray();
    27             TrieNode node = root;
    28             for(int j=0; j<wa.length; j++) node = node.append(wa[j]);
    29             node.word = words[i];
    30         }
    31         boolean[][] visited = new boolean[board.length][board[0].length];
    32         for(int i=0; i<board.length; i++) {
    33             for(int j=0; j<board[i].length; j++) {
    34                 if (root.nexts[board[i][j]-'a'] != null) find(board, visited, i, j, root, founded);
    35             }
    36         }
    37         List<String> results = new ArrayList<>();
    38         results.addAll(founded);
    39         return results;
    40     }
    41 }
    42 class TrieNode {
    43     String word;
    44     TrieNode[] nexts = new TrieNode[26];
    45     TrieNode append(char ch) {
    46         if (nexts[ch-'a'] != null) return nexts[ch-'a'];
    47         nexts[ch-'a'] = new TrieNode();
    48         return nexts[ch-'a'];
    49     }
    50 }

    ] = new TrieNode(); return nexts[ch-'a']; }}

  • 相关阅读:
    android Dialog 底部弹出
    L2-023. 图着色问题(暴力)
    L2-023. 图着色问题(暴力)
    L2-022. 重排链表
    L2-022. 重排链表
    L2-020. 功夫传人(dfs+vector 或者 邻接矩阵+dij+优先队列)
    L2-020. 功夫传人(dfs+vector 或者 邻接矩阵+dij+优先队列)
    愿天下有情人都是失散多年的兄妹(bfs)
    愿天下有情人都是失散多年的兄妹(bfs)
    循环赛日程表(分治)
  • 原文地址:https://www.cnblogs.com/kexinxin/p/10203034.html
Copyright © 2011-2022 走看看