题目:矩阵单词搜索

难度: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(矩阵单词搜索)的更多相关文章

  1. 【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 ...

  2. 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 ...

  3. LeetCode第[33]题(Java):Search in Rotated Sorted Array

    题目:在翻转有序中搜索 难度:Medium 题目内容: Suppose an array sorted in ascending order is rotated at some pivot unkn ...

  4. LeetCode第[34]题(Java):Search for a Range

    题目:搜索目标范围 难度:Medium 题目内容: Given an array of integers nums sorted in ascending order, find the starti ...

  5. 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 + ...

  6. 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 ...

  7. LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2

    题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...

  8. 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 ...

  9. 【LeetCode-面试算法经典-Java实现】【079-Word Search(单词搜索)】

    [079-Word Search(单词搜索)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a 2D board and a word, find if ...

随机推荐

  1. SQL事务回滚 写法(转)

    以下是SQL 回滚的语句:方案一:SET   XACT_ABORT   ON--如果产生错误自动回滚GOBEGIN   TRANINSERT   INTO   A   VALUES   (4)INSE ...

  2. intellij idea 重命名或复制一个项目(不用重启)

    Idea 内无法直接修改Explorer 里文件夹的名称,只能手动改文件夹的名称. 目前找到的最好的方法: 1)重命名一个项目 在Idea 项目关闭状态下,在 Explorer (Windows) / ...

  3. 数据库之ADO

    ADO是一种跨多种语言的数据库访问技术. 在MFC里面微软公司将这些函数封装为以下几个类. 在VS2013版本的MFC中,这些类是如下定义的. CDaoDatabase Class:https://m ...

  4. python 之操作redis数据库(非关系型数据库,k-v)

    数据库: 1. 关系型数据库 表结构 2. 非关系型数据库 nosql (k - v 速度快),常用的时以下三种: memcache 存在内存里 redis 存在内存里 mangodb 数据还是存在磁 ...

  5. BZOJ 1316: 树上的询问

    挺裸的点分治 刚开始想用map水过去,然后做p次点分治,然后T到自闭 最后发现可以sort一遍,然后去重,记录每个数出现的次数,这样就可以双指针,不会漏掉了 #include <bits/std ...

  6. 2017 Multi-University Training Contest - Team 3 Kanade's sum hd6058

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6058 题目: Kanade's sum Time Limit: 4000/2000 MS (J ...

  7. Linux树莓派中/etc/rc.local不执行的问题

    最近研究在树莓派中嵌入式开发java程序,并打算和Salesforce进行通信.需要开发一个java的web server,不想弄那么复杂,于是打算在linux系统中/etc/rc.local写想要执 ...

  8. tomcat进程意外退出的问题分析(转)

    原文链接:http://hongjiang.info/why-kill-2-cannot-stop-tomcat/ 节前某个部门的测试环境反馈tomcat会意外退出,我们到实际环境排查后发现不是jvm ...

  9. 深入学习js之——词法作用域和动态作用域

    开篇 当我们在开始学习任何一门语言的时候,都会接触到变量的概念,变量的出现其实是为了解决一个问题,为的是存储某些值,进而,存储某些值的目的是为了在之后对这个值进行访问或者修改,正是这种存储和访问变量的 ...

  10. git推送到github报错:error: The requested URL returned error: 403 Forbidden while accessing https://github.com

    最近使用git命令从github克隆仓库到版本,然后进行提交到github时报错如下: [root@node1 git_test]# git push origin mastererror: The ...