212.word-search-ii.java 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import java.util.LinkedList;
  2. class Solution {
  3. private int[] dy = new int[]{0, 1, 0, -1};
  4. private int[] dx = new int[]{1, 0, -1, 0};
  5. private char[][] board;
  6. private int n;
  7. private int m;
  8. private TrieNode root;
  9. public List<String> findWords(char[][] board, String[] words) {
  10. LinkedList<String> res = new LinkedList<>();
  11. if ((n = board.length) == 0 || (m = board[0].length) == 0 || words.length == 0) return res;
  12. this.board = board;
  13. root = new TrieNode();
  14. root.cnt = -1;
  15. for (String word : words) root.insert(word);
  16. boolean[][] used = new boolean[n][m];
  17. for (int y = 0; y < n; y++) {
  18. for (int x = 0; x < m; x++) {
  19. StringBuilder sb = new StringBuilder();
  20. backtrack(y, x, root, sb, used, res);
  21. }
  22. }
  23. return res;
  24. }
  25. private void backtrack(int y, int x, TrieNode curr, StringBuilder sb, boolean[][] used, LinkedList<String> res) {
  26. if (curr == null || curr.cnt == 0) return;
  27. if (curr.isKey) {
  28. res.add(sb.toString());
  29. root.remove(sb.toString());
  30. }
  31. if (y < 0 || n <= y || x < 0 || m <= x || used[y][x]) return;
  32. char c = board[y][x];
  33. sb.append(c);
  34. used[y][x] = true;
  35. curr = curr.next[(int) c - 'a'];
  36. for (int i = 0; i < 4; i++) {
  37. int ny = y + dy[i], nx = x + dx[i];
  38. backtrack(ny, nx, curr, sb, used, res);
  39. }
  40. sb.deleteCharAt(sb.length() - 1);
  41. used[y][x] = false;
  42. }
  43. class TrieNode {
  44. int cnt;
  45. boolean isKey;
  46. TrieNode[] next = new TrieNode[26];
  47. void insert(String str) {
  48. TrieNode curr = this;
  49. for (char c : str.toCharArray()) {
  50. int i = (int) c - 'a';
  51. if (curr.next[i] == null) curr.next[i] = new TrieNode();
  52. curr = curr.next[i];
  53. curr.cnt++;
  54. }
  55. curr.isKey = true;
  56. }
  57. void remove(String str) {
  58. TrieNode curr = this;
  59. for (char c : str.toCharArray()) {
  60. int i = (int) c - 'a';
  61. curr = curr.next[i];
  62. curr.cnt--;
  63. }
  64. curr.isKey = false;
  65. }
  66. }
  67. }