加载中...
79-单词搜索(Word Search)
发表于:2021-12-03 | 分类: 中等
字数统计: 442 | 阅读时长: 2分钟 | 阅读量:

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

英文原文

Given an m x n grid of characters board and a string word, return true if word exists in the grid.

The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.

 

Example 1:

Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
Output: true

Example 2:

Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
Output: true

Example 3:

Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
Output: false

 

Constraints:

  • m == board.length
  • n = board[i].length
  • 1 <= m, n <= 6
  • 1 <= word.length <= 15
  • board and word consists of only lowercase and uppercase English letters.

 

Follow up: Could you use search pruning to make your solution faster with a larger board?

中文题目

给定一个 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
  • boardword 仅由大小写英文字母组成

 

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

通过代码

高赞题解

这是一个使用回溯算法解决的问题,涉及的知识点有 深度优先遍历状态重置

<79-1.png,79-2.png,79-3.png,79-4.png,79-5.png,79-6.png,79-7.png,79-8.png,79-9.png,79-10.png,79-11.png,79-12.png,79-13.png>

参考代码

[]
public class Solution { private static final int[][] DIRECTIONS = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}}; private int rows; private int cols; private int len; private boolean[][] visited; private char[] charArray; private char[][] board; public boolean exist(char[][] board, String word) { rows = board.length; if (rows == 0) { return false; } cols = board[0].length; visited = new boolean[rows][cols]; this.len = word.length(); this.charArray = word.toCharArray(); this.board = board; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (dfs(i, j, 0)) { return true; } } } return false; } private boolean dfs(int x, int y, int begin) { if (begin == len - 1) { return board[x][y] == charArray[begin]; } if (board[x][y] == charArray[begin]) { visited[x][y] = true; for (int[] direction : DIRECTIONS) { int newX = x + direction[0]; int newY = y + direction[1]; if (inArea(newX, newY) && !visited[newX][newY]) { if (dfs(newX, newY, begin + 1)) { return true; } } } visited[x][y] = false; } return false; } private boolean inArea(int x, int y) { return x >= 0 && x < rows && y >= 0 && y < cols; } }

说明

  1. 偏移量数组在二维平面内是经常使用的,可以把它的设置当做一个技巧,并且在这个问题中,偏移量数组内的 4 个偏移的顺序无关紧要;

说明:类似使用这个技巧的问题还有:「力扣」第 130 题:被围绕的区域「力扣」第 200 题:岛屿数量

  1. 对于这种搜索算法,我认为理解 DFS 和状态重置并不难,代码编写也相对固定,难在代码的编写和细节的处理,建议多次编写,自己多总结多思考,把自己遇到的坑记下。

我自己在写

for i in range(m):
    for j in range(n):
        # 对每一个格子都从头开始搜索
        if self.__search_word(board, word, 0, i, j, marked, m, n):
            return True

这一段的时候,就写成了:

# 这一段代码是错误的,不要模仿
for i in range(m):
    for j in range(n):
        # 对每一个格子都从头开始搜索
        return self.__search_word(board, word, 0, i, j, marked, m, n)

这样其实就变成只从坐标 (0,0) 开始搜索,搜索不到返回 False,但题目的意思是:只要你的搜索返回 True 才返回,如果全部的格子都搜索完了以后,都返回 False ,才返回 False

统计信息

通过次数 提交次数 AC比率
243076 529174 45.9%

提交历史

提交时间 提交结果 执行时间 内存消耗 语言

相似题目

题目 难度
单词搜索 II 困难
上一篇:
78-子集(Subsets)
下一篇:
80-删除有序数组中的重复项 II(Remove Duplicates from Sorted Array II)
本文目录
本文目录