79. 单词搜索
创始人
2024-03-08 03:56:21

79. 单词搜索

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

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

示例 1:

在这里插入图片描述

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true

示例 2:

在这里插入图片描述

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “SEE”
输出:true

示例 3:

在这里插入图片描述

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCB”
输出:false

提示:

  • m == board.length
  • n = board[i].length
  • 1 <= m, n <= 6
  • 1 <= word.length <= 15
  • board 和 word 仅由大小写英文字母组成

**进阶:**你可以使用搜索剪枝的技术来优化解决方案,使其在 board 更大的情况下可以更快解决问题?

思路:(回溯暴力搜索)

整体思路
使用深度优先搜索(DFS) 和回溯的思想实现。在访问过程中要设置一个二维数组标记元素 hasVisited 是否被访问过。

外层遍历
遍历 board 的所有元素, 并定义函数,从每个结点内层遍历,传入以下参数;

  • 变量 k 记录已经匹配的长度
  • 该节点的行 r 列 c 坐标
  • 数组的遍历情况 hasVisited
  • 原字符数组 board
  • 需要搜索的字符串 word

内层遍历:递归 + 回溯

  • 定义递归返回条件
  • 边界情况及不符情况判断
  • 如果符合,把该节点标记为已访问
  • 再从该节点出发,从四个方向依次递归调用,并判断
  • 递归结束后,回溯,即将该节点置位未访问

代码:(Java)

public class words_search {public static void main(String[] args) {// TODO 自动生成的方法存根char[][] board = {{'A', 'B', 'C', 'E'},{'S', 'F', 'C', 'S'},{'A', 'D', 'E', 'E'}};String word = "ABCB";System.out.println(exist(board, word));}private static int [][] dircetions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};//可有走的四个方向private static int m;private static int n;public static boolean exist(char[][] board, String word) {if(word == null || word.length() == 0) {return true;}if(board == null || board.length == 0 || board[0].length == 0) {return false;}m = board.length;//行n = board[0].length;//列boolean [][] hasVisited = new boolean[m][n];//是否被访问for(int r = 0; r < m; r++) {for(int c = 0; c < n; c++) {if(backtracking(0, r, c, hasVisited, board, word)) {//数组中的每一个字母都可以当做首字母return true;}}}return false;}private static boolean backtracking(int k, int r, int c, boolean[][] hasVisited, char[][] board, String word) {// TODO 自动生成的方法存根if(k == word.length()) {//比对完成,返回return true;}if(r < 0 || r >= m || c < 0 || c >= n || board[r][c] != word.charAt(k) || hasVisited[r][c]) {//边界及不符合判断return false;}hasVisited[r][c] = true;//访问for(int [] d : dircetions) {//四个方向依次遍历if(backtracking(k + 1, r + d[0], c + d[1], hasVisited, board, word)){return true;}}hasVisited[r][c] = false;//回溯return false;}
}

复杂度分析:

  • 时间复杂度:一个非常宽松的上界为 O(MN⋅3L)O(MN⋅3^L)O(MN⋅3L),其中 M,N为网格的长度与宽度,L 为字符串 word 的长度。在每次调用函数 backtracking 时,除了第一次可以进入 4 个分支以外,其余时间我们最多会进入 3 个分支(因为每个位置只能使用一次,所以走过来的分支没法走回去)。由于单词长为 L ,故 backtracking 的时间复杂度为 O(3L)O(3^L)O(3L),而我们要执行 O(MN)次检查。然而,由于剪枝的存在,我们在遇到不匹配或已访问的字符时会提前退出,终止递归流程。因此,实际的时间复杂度会远远小于 O(MN⋅3L)O(MN⋅3^L)O(MN⋅3L)。

  • 空间复杂度:O(MN)。我们额外开辟了 O(MN) 的 hasVisited 数组,同时栈的深度最大为O(min⁡(L,MN)) 。

注:仅供学习参考!

题目来源:力扣

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...