单词搜索

题目描述:给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例说明请见LeetCode官网。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/word-search/

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一:回溯算法

首先,直接判断2种特殊场景:

  • 如果要匹配的字符串为空,直接返回true;
  • 如果board数组为空,直接返回false。

否则,先声明一个和board同样大小的boolean类型的数组,记录当前单元格是否已经走过,然后遍历board的每一个字符,对每一个字符和word第一个字符相等的时候,调用回溯方法进行判断以当前字符为起点是否能够匹配word字符串,如果能返回true,否则继续遍历下一个字符。最后,如果没有匹配成功,返回false。

public class LeetCode_079 {
public static boolean exist(char[][] board, String word) {
/**
* 如果要匹配的字符串为空,直接返回true
*/
if (word == null || word.length() == 0) {
return true;
}
/**
* 如果board数组为空,直接返回false
*/
if (board == null || board.length == 0 || board[0].length == 0) {
return false;
}
/**
* 声明一个和board同样大小的boolean类型的数组,记录当前单元格是否已经走过
*/
boolean[][] visited = new boolean[board.length][board[0].length];
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
/**
* 对每一个字符和word第一个字符相等的时候,调用方法进行判断
*/
if (board[i][j] == word.charAt(0) && exist(board, visited, word, i, j, 0)) {
return true;
}
}
}
return false;
} /**
* 回溯算法
*
* @param board 原字符网格
* @param visited 和board大小相同的boolean类型的网格,标识当前字符是否走过
* @param word 要匹配的单词
* @param startX 当前单元格的x坐标
* @param startY 当前单元格的y坐标
* @param pos 当前已经匹配了几个字符
* @return
*/
private static boolean exist(char[][] board, boolean[][] visited, String word, int startX, int startY, int pos) {
if (board[startX][startY] != word.charAt(pos)) {
// 如果当前单元格和要匹配的字符不同,直接返回false
return false;
} else if (pos == word.length() - 1) {
// 如果已经匹配的字符数和word的长度相等,则说明已经匹配成功,返回true
return true;
} visited[startX][startY] = true;
// 当前单元格可以往四个方向移动
int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
boolean result = false;
for (int[] dir : directions) {
int nextStartX = startX + dir[0], nextStartY = startY + dir[1];
if (nextStartX >= 0 && nextStartX < board.length && nextStartY >= 0 && nextStartY < board[0].length) {
if (!visited[nextStartX][nextStartY]) {
boolean flag = exist(board, visited, word, nextStartX, nextStartY, pos + 1);
if (flag) {
result = true;
break;
}
}
}
}
visited[startX][startY] = false;
return result;
} public static void main(String[] args) {
char[][] board = new char[][]{{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}};
// 测试用例,期望返回: true
System.out.println(exist(board, "ABCCED"));
}
}

【每日寄语】 逆境、是非来临,心中要持一“宽”字。

最新文章

  1. Mono 3.2.3 Socket功能迎来一稳定的版本
  2. 在MotionBuilder中绑定C3D动作和模型
  3. form表单中enctype=&quot;multipart/form-data&quot;的作用
  4. python之计算器(第四天)
  5. LAMP理论整理
  6. java-二维码编写zxing
  7. hiveserver2
  8. Linux内核分析——跟踪分析Linux内核的启动过程
  9. MemSQL Start[c]UP 2.0 - Round 1
  10. 学习笔记之NodeJs基本操作
  11. Microsoft dynamic sdk中join应该注意的问题.
  12. Python之旅.第三章.函数3.30
  13. flask 面试题
  14. laravel项目安装
  15. [原][openstack-pike][controller node][issue-2][glance] Could not parse rfc1738 URL from string &#39;mysql+pymysql=http://glance:glance@controller/glance&#39;
  16. gnats配置文件
  17. 计时器---JS
  18. Quartz的集群模式和单机模式共存-让一个非集群的Quartz与集群节点并行着运行
  19. POJ 1986 - Distance Queries - [LCA模板题][Tarjan-LCA算法]
  20. 彩信的在android里是如何存储的 Android MMS模块数据存取

热门文章

  1. 你我都会遇到的需求:如何导出MySQL中的数据~ 简单!实用!
  2. halcon视觉入门钢珠识别
  3. JavaScript的内存管理
  4. JAVA多线程学习四 - CAS(乐观锁)
  5. Java中的UIManager简单实用(皮肤包)
  6. NSMutableArray基本概念
  7. hibernate中的一级缓存与闪照区
  8. 一致性协议之ZAB
  9. Spring系列11:@ComponentScan批量注册bean
  10. springboot自动扫描添加的BeanDefinition源码解析