Leetcode之回溯法专题-212. 单词搜索 II(Word Search II)
Leetcode之回溯法专题-212. 单词搜索 II(Word Search 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(前缀树)。
分析:题中提示里写前缀树可以解这题,但我做的时候没看到,硬用回溯+DFS做出来的,时间复杂度很高,二刷的时候再优化吧。
是79题的升级版,同样也是地图题,需要vis数组来控制,具体见79题。
class Solution { List<String> ans = new ArrayList<>(); int dirx[] = new int[]{0,0,1,-1}; int diry[] = new int[]{1,-1,0,0}; int vis[][] = null; public List<String> findWords(char[][] board, String[] words) { vis = new int[board.length][board[0].length]; List<String> list = Arrays.asList(words); int maxLen = getMaxLen(list); for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[0].length; j++) { if(list.size()!=0){ vis[i][j] = 1; dfs(board,list,i,j,vis,board[i][j]+"",maxLen); vis[i][j] = 0; } } } return ans; } public void dfs(char[][] board,List<String> words,int x,int y,int[][] vis,String now,int maxLen){ if(now.length()>maxLen){ return; } if(words.contains(now) && !ans.contains(now)){ ans.add(now); } if(!hasPrefix(now, words)){ return; } for(int i=0;i<4;i++){ int xx = x + dirx[i]; int yy = y + diry[i]; if(xx>=0 && xx<board.length && yy>=0 && yy<board[0].length && vis[xx][yy]==0){ vis[xx][yy] = 1; dfs(board,words,xx,yy,vis,now+board[xx][yy],maxLen); vis[xx][yy] = 0; } } } public int getMaxLen(List<String> list){ int max = 0; if(list.size()==0) return 0; for (String string : list) { max = Math.max(max, string.length()); } return max; } public boolean hasPrefix(String prefix,List<String> list){ int len = prefix.length(); for (String string : list) { if(string.length()>=len && string.substring(0, len).equals(prefix)){ return true; } } return false; } }
作者:秦羽纶
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.