难度:Hard
说明:
给出二维数组arr,以及一个需要匹配的字符串数组strArr,然后在arr其中找到strArr的字符,需要是数组内连续的字符串,不限制方向,但是匹配时候只能用一次,题目确实比较绕,不过题意如此。
问题链接:https://leetcode.com/problems/word-search-ii/
相关算法:
P1002-过河卒:https://blog.csdn.net/qq_28033719/article/details/106261183
输入案例:
Input: board = [ ['o','a','a','n'], ['e','t','a','e'], ['i','h','k','r'], ['i','f','l','v'] ] words = ["oath","pea","eat","rain"] // o - a - t - h从(0,0) - (0,1) - (1,1) - (2,1) // e - a - t从(3,1) - (2,1) - (1,1) Output: ["eat","oath"]相对来说比较困难,我一开始以为用Rabin-Karp算法,但是发现运算量会很大,而且也吃内存。
看提示就说用字典树,我开始用字典树给二维数组打(疯了),然后换成给strArr弄成字典树就好。
然后就是常见的图形搜索,用DFS,DFS用递归,二维数组DFS的坐标比较适合递归处理。
class Solution { static int x; static int y; // 结果集并且用hash去重 HashSet<String> set; static char[][] board2; public List<String> findWords(char[][] board, String[] words) { // 将words全部存入字典树 Tree root = new Tree(); board2 = board; words2 = words; for(int i = 0;i < words.length;i ++) { String str = words[i]; Tree tree = root; for(char ch : str.toCharArray()) { int index = ch - 'a'; Tree next = tree.next[index] == null ? new Tree() : tree.next[index]; tree.next[index] = next; tree = next; } tree.end = true; tree.index = i; } // 将二维数组遍历一遍 set = new HashSet<String>(); x = board2.length; y = board2[0].length; int c = x * y; for(int i = 0;i < x;i ++) { for(int j = 0;j < y;j ++) { int index = board2[i][j] - 'a'; if(root.next[index] != null) { // 为了不重复利用,设置参观表 boolean[][] visited = new boolean[x][y]; search(root,index, i,j,visited); } } } return new ArrayList<String>(set); } static String[] words2; // 方向,为了减少代码量 static int[][] direct = new int[][]{{1,0},{-1,0},{0,1},{0,-1}}; public void search(Tree root,int index, int i, int j, boolean[][] visited) { if(root.next[index] != null) { // 匹配到为true visited[i][j] = true; if(root.next[index].end) set.add(words2[root.next[index].index]); for(int[] arr : direct) { int x1 = i + arr[0]; int y1 = j + arr[1]; // 不约边,并且不重复浏览visited if(x1 >= 0 && x1 < x && y1 >= 0 && y1 < y && !visited[x1][y1]) { search(root.next[index],board2[x1][y1] - 'a',x1,y1,visited); } } // 处理完成变为false visited[i][j] = false; } } } class Tree { Tree[] next = new Tree[26]; boolean end = false; int index = 0; }