212 单词搜索II
难度:困难
平台:leetcode
Description
给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
示例: 1
2
3
4
5
6
7
8
9
10
11输入:
words = ["oath","pea","eat","rain"]
board =
[
['o','a','a','n'],
['e','t','a','e'],
['i','h','k','r'],
['i','f','l','v']
]
输出:["eat","oath"]
你可以假设所有输入都由小写字母 a-z 组成。
原题链接
MySolution
这类字符串多模式匹配题目,第一反映是前缀树,关于前缀树在这里就不过多介绍了。此题基本思路是,将words字符串数组构造成前缀树,然后对board的每个字符用前缀树去匹配。当时做这道题花了一定的时间主要是因为用前缀树去匹配时涉及状态回溯,要在每次失败或者结束后回到上一个状态,并且不可遗漏,一开始写题时没有考虑周到。接下来上拆解代码。 ### 结点定义 1
2
3
4
5
6
7
8
9
10
11class node{
//节点结构
ArrayList<node> nodes=new ArrayList<node>();
boolean isEnd;
char value;
public node(boolean isEnd, char value) {
super();
this.isEnd = isEnd;
this.value = value;
}
}
构造前缀树
1 | public void init(String[] words) { |
前缀树匹配
前缀树匹配时采用递归+回溯的思想 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32public void find(int i,int j,node cur,int[][] visited,String rString) {
if(i<m && i>=0 && j>=0 &&j<n && visited[i][j]!=1) //判断边界
{
visited[i][j]=1;
for(node n:cur.nodes) //遍历当前节点子结点
{
if(boards[i][j]!=n.value) //子节点未找到相同字母
continue;
else //子节点找到相同字母
{
rString+=boards[i][j];//添加到结果String
if (n.isEnd) //添加到结果String集
result.add(rString);
cur=n;//子节点变成当前结点
if(n.nodes.isEmpty()) {
visited[i][j]=0;
return;
}
for(int k=0;k<4;k++) {
find(i+x[k], j+y[k], cur, visited, rString);
}
//查询四周
visited[i][j]=0;
}
}
//子节点内无相同结点
visited[i][j]=0;
return;
}else {
return;
}
}
整体代码
1 | import java.util.*; |
有的没的
这一分类主要记录自己做过的一些还比较有意义的题目的解题历程以及一些个人思考,菜鸡起步而已,希望自己能坚持下去,然后能有所进步吧。