LeetCode第[79]题(Java):Word Search(矩阵单词搜索)
题目:矩阵单词搜索
难度:Medium
题目内容:
Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
翻译:
给定一个2D的字符数组和一个单词,找出这个词是否存在于网格中。
这个词可以用顺序相邻的细胞的字母来构造,在那里“相邻”的细胞是水平的或垂直的相邻的。同一个字母单元可能不止一次使用。
Example:
board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
] Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.
我的思路:对整个二维数组进行循环,对于每一个字母都进入递归方法,
1、判断当前字符如果不与传入字符串第一个字母匹配,或者访问过则返回fasle;
2、这是最后一个字符,返回true;(已经通过上面的判断已经是匹配的)
3、将此位置的访问符置1,然后分别向上、下、左、右四个方向调用递归方法;
4、四个方向访问完毕,说明由此处开始的路径已经有结果,将此位置访问符再置0,并返回四个方向的“或”。
为什么又要再置0?
因为整个递归过程就只有一个used访问标志矩阵(引用类型),如果每次访问后就设置1,不再管,那么之前已经失败的路径就会对之后再访问的路径(对于此路径是新访问的)产生影响。
此处的访问符类 used 似于第[47]题Permutations 2 中的used使用方法是一样的,不过意义不同,
所以,若在递归中有包含访问符,调用递归结束后,访问符应该置0(或false)
我的代码:
public boolean exist(char[][] board, String word) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (find(word, i, j, board, new int[board.length][board[0].length])) {
return true;
}
}
}
return false;
} private boolean find(String word, int i, int j, char[][] board, int[][] used) {
if (i < 0 || i > board.length-1 || j < 0 || j > board[0].length-1) {
return false;
}
if (board[i][j] != word.charAt(0) || used[i][j] == 1) {
return false;
} else if (word.length() == 1) {
return true;
}
used[i][j] = 1;
boolean ans = find(word.substring(1), i-1, j, board, used)
|| find(word.substring(1), i+1, j, board, used)
|| find(word.substring(1), i, j-1, board, used)
|| find(word.substring(1), i, j+1, board, used);
used[i][j] = 0;
return ans;
}
我的复杂度:O((m*n)2)
编码过程中的问题:
1、之前采用的是先判断首字母是匹配然后直接返回find方法的结果,后来发现这样做是不行的,因为如果在正确答案的前面如果有一个是前面匹配后面不匹配的错误答案,就会直接返回错误答案的false;——————如果 true 则return true,否则继续
2、之前没考虑到标志位,从而路径会往回找;“【【a,a】】” “aaa”
3、之前是用了四个标志位“up-down-left-right”,每次都判断是否能上下左右再进行递归调用,如下:
if (i > 0) {
up = find(word.substring(1), i-1, j, board, used);
}
然后最后再对这四个标志位进行 或 运算,但是这样做路径中的字母每次都会进行四个递归,没有短路的可能,所以当需要方法多分支递归的时候,最好改成直接调用方法进行 短路与或 运算, 然后在方法的开头加入此结果的判断,这样能减少不少多余的运算。【本题将是否能上下左右的判断加入到了递归方法的最开始】
4、本方法其实还可以优化,就是将访问过的字符用“*”表示,在递归结束后再设置成原来的值,这样就可以省去新建一个标志矩阵。
答案代码:
public boolean exist(char[][] board, String word) {
char[] w = word.toCharArray();
for (int y=0; y<board.length; y++) {
for (int x=0; x<board[y].length; x++) {
if (exist(board, y, x, w, 0)) return true;
}
}
return false;
} private boolean exist(char[][] board, int y, int x, char[] word, int i) {
if (i == word.length) return true;
if (y<0 || x<0 || y == board.length || x == board[y].length) return false;
if (board[y][x] != word[i]) return false;
board[y][x] ^= 256;
boolean exist = exist(board, y, x+1, word, i+1)
|| exist(board, y, x-1, word, i+1)
|| exist(board, y+1, x, word, i+1)
|| exist(board, y-1, x, word, i+1);
board[y][x] ^= 256;
return exist;
}
答案思路:
基本思路是一样的,不过有两个亮点是比我的方法好的:
1、利用char[] 和 一个 int 表示当前所在第几个字母,代替了频繁利用subString来新建一个字符串;
2、利用二进制运算 与或 的特性——与或全1,再与或全1就会等于自己,因为说好都是字母,而且字母为65~90,95~122内,所以与或128也是可以的。从而不必再用temp了。
LeetCode第[79]题(Java):Word Search(矩阵单词搜索)的更多相关文章
- 【LeetCode每天一题】Word Search(搜索单词)
Given a 2D board and a word, find if the word exists in the grid.The word can be constructed from le ...
- LeetCode 79. Word Search(单词搜索)
Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...
- LeetCode第[33]题(Java):Search in Rotated Sorted Array
题目:在翻转有序中搜索 难度:Medium 题目内容: Suppose an array sorted in ascending order is rotated at some pivot unkn ...
- LeetCode第[34]题(Java):Search for a Range
题目:搜索目标范围 难度:Medium 题目内容: Given an array of integers nums sorted in ascending order, find the starti ...
- LeetCode第[18]题(Java):4Sum 标签:Array
题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + ...
- LeetCode第[1]题(Java):Two Sum 标签:Array
题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...
- LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2
题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...
- LeetCode第[1]题(Java):Two Sum (俩数和为目标数的下标)——EASY
题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...
- 【LeetCode-面试算法经典-Java实现】【079-Word Search(单词搜索)】
[079-Word Search(单词搜索)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a 2D board and a word, find if ...
随机推荐
- OCR技术浅探: 语言模型和综合评估(4)
语言模型 由于图像质量等原因,性能再好的识别模型,都会有识别错误的可能性,为了减少识别错误率,可以将识别问题跟统计语言模型结合起来,通过动态规划的方法给出最优的识别结果.这是改进OCR识别效果的重要方 ...
- 基于Hadoop的数据仓库Hive
Hive是基于Hadoop的数据仓库工具,可对存储在HDFS上的文件中的数据集进行数据整理.特殊查询和分析处理,提供了类似于SQL语言的查询语言–HiveQL,可通过HQL语句实现简单的MR统计,Hi ...
- webuploader 多图片上传
WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件. 具体接口参考 webuploader接口文档地址 一.图片上传功能 ...
- golang build error: syntax error: nested func not allowed
在笔记本中写了一个简易web程序,但是编译失败,提示“syntax error: nested func not allowed” . 不明白什么意思,幸好代码量小,原来是方法的末尾的“}”丢了! p ...
- PAT 1063 Set Similarity[比较]
1063 Set Similarity (25 分) Given two sets of integers, the similarity of the sets is defined to be N ...
- Windows下IIS+PHP 5.2的安装与配置
Windows下IIS+PHP 5.2的安装与配置 Windows下PHP的安装虽然简单,但如果不注意方法,仍然会让你头疼.此外,PHP 5.2版本与之前4.x版本也有一些不同,所以有必要记录一下 ...
- Oracle Union Union All 对查询结果集操作
在Oracle中提供了三种类型的集合操作: 并(UNION).交(INTERSECT).差(MINUS) Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序: Union Al ...
- 131. Palindrome Partitioning(回文子串划分 深度优先)
Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...
- Django Restful API Class Based View
基于class定义view 前言: 我们首先通过以class的方式重写view,我们可以自己构造类也可以通过res_framework 提供的mixins和generics类库直接构造类 下面来看下自 ...
- lastIndexOf is not a function
最近在开发的时候遇到了这个问题lastIndexOf is not a function,细心调试发现我传递进去的参数不是字符串类型,而且object类型,导致出现这种错误.把参数修改成字符串传递进去 ...