首页 > 其他分享 >LeetCode刷题之HOT100之单词搜索

LeetCode刷题之HOT100之单词搜索

时间:2024-06-12 10:33:17浏览次数:17  
标签:int MN mark 单词 boolean HOT100 board LeetCode 刷题

2024/6/12 这两天天气只能用闷、潮、热来描述。整个人像被罩在为了饭菜保温的盖子里,喘气困难、粘稠的空气一次又一次打湿我。唯有空调救我,夏天来了。Anyway,昨天只做了一题,今天早点来做一题。

1、题目描述

在这里插入图片描述

2、逻辑分析

给定一个二维字符矩阵和一个单词,求单词是否在这个二维矩阵中,规则是,单词要按照顺序来,每次只能向上下、左右移动。大致就是这么个意思。我的想法是:既然需要单词必须按照字母排序,那么就以单词作为出发点,遍历单词,然后在矩阵中找是否有这个单词,找到后再与相连的单词进行位置计较,看是否符合规则。那么,怎么用代码来实现呢?我想不出来,故看了题解,题解使用回溯思想来解决。
整体思路:使用深度优先搜索(DFS)和回溯的思想实现。关于判断元素是否使用过,我用了一个二维数组 mark 对使用过的元素做标记。

  1. 首先遍历 board 的所有元素,先找到和 word 第一个字母相同的元素,然后进入递归流程。假设这个元素的坐标为 (i,
    j),进入递归流程前,先记得把该元素打上使用过的标记mark[i][j] = true
  2. 好了,打完标记了,现在我们进入了递归流程。递归流程主要做了这么几件事: 从 (i, j) 出发,朝它的上下左右试探,看看它周边的这四个元素是否能匹配 word 的下一个字母
  3. 如果匹配到了:带着该元素继续进入下一个递归
  4. 如果都匹配不到:返回 False
  5. 当 word 的所有字母都完成匹配后,整个流程返回 True
    注意事项:
    递归时元素的坐标是否超过边界
    回溯标记 mark[i][j] = 0以及 return 的时机

3、代码演示

 public boolean exist(char[][] board, String word) {
        // 获取board的行数和列数 
        int n = board.length, m = board[0].length;
        // 创建一个与board同样大小的二维布尔数组,用于记录某个位置是否已被访问
        boolean [][] mark = new boolean[n][m];
        // 遍历board中的每一个字符 
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                // 从当前字符开始,检查是否可以通过DFS找到整个word
                boolean flag = check(board, mark, i, j, word, 0);
                // 如果找到了,直接返回true 
                if(flag){
                    return true;
                }
            }          
        }
        // 如果遍历完整个board都没有找到,返回false
         return false; 
    }

    // 递归检查函数  
    // 从(i,j)位置开始,检查board中是否包含字符串s的剩余部分(从索引k开始)
    public boolean check(char[][] board, boolean[][] mark, int i, int j, String s, int k){
        // 如果当前字符与s的第k个字符不匹配,返回false 
        if(board[i][j] != s.charAt(k)){
            return false;
        // 如果已经检查完s的所有字符,返回true
        }else if(k == s.length() - 1){
            return true;
        }
        // 标记当前位置为已访问
        mark[i][j] = true;
        // 定义四个方向的偏移量
        int[][] directions = {{0,1},{0,-1},{1,0},{-1,0}};
        boolean result = false;
        // 遍历四个方向
        for(int[] dir : directions){
            int newi = i + dir[0], newj = j + dir[1];
            // 确保新位置在board范围内且未被访问过 
            if(newi >= 0 && newi < board.length && newj >= 0 && newj < board[0].length){
                // 递归检查新位置
                if(!mark[newi][newj]){
                    boolean flag = check(board, mark, newi, newj, s, k + 1);
                    // 如果在新位置找到了s的剩余部分,则result设为true并退出循环
                    if(flag){
                        result = true;
                        break;
                    }
                }
            }
        }
        // 回溯,将当前位置标记为未访问
        mark[i][j] = false;
        // 返回结果
        return result;
    }

是的,我基本上是照着题解敲出来的,敲的过程中印象加深,体会了dfs与回溯之间的关系与使用,以上注释较清晰,下面分析一下复杂度。

4、复杂度分析

  • 时间复杂度: O ( M N ⋅ 3 L ) \text{}O(MN\cdot3^{L}) O(MN⋅3L)。其中 M , N为网格的长度与宽度,L 为单词 word 的长度。在每次调用函数 check 时,除了第一次可以进入 4 个分支以外,其余时间我们最多会进入 3 个分支(因为每个位置只能使用一次,所以走过来的分支没法走回去)。由于单词长为 L,故调用check 的时间复杂度为 O ( 3 L ) O(3^{L}) O(3L)。要执行 O ( M N ) O(MN) O(MN)次检查。故时间复杂度为 O ( M N ⋅ 3 L ) \text{}O(MN\cdot3^{L}) O(MN⋅3L)。
  • 空间复杂度: O ( M N ) O(MN) O(MN)。因为需要创建一个与board一样大小的数组mark来存储元素是否被访问过。

做完啦啦啦,拜拜啦!

标签:int,MN,mark,单词,boolean,HOT100,board,LeetCode,刷题
From: https://blog.csdn.net/weixin_48424783/article/details/139613942

相关文章

  • 代码随想录 算法训练营 d6 哈希表 Leetcode242 有效的字母异位词 Leetcode349 两个数
    哈希表很重要哈希表哈希表场景一般哈希表都是用来快速判断一个元素是否出现集合里一般来说数组模拟哈希set 哈希map不同的场景 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,se......
  • 基于SpringBoot的刷题小程序的设计与实现+附源码+数据库
    摘要:随着互联网技术的快速发展,在线教育平台逐渐成为学生学习和复习的重要工具。为了提高用户在学习过程中的效率和体验,本文提出并实现了一个基于SpringBoot的刷题小程序。该小程序旨在通过高效的题库管理、智能化的刷题功能以及友好的用户界面,帮助用户更好地进行知识点的巩......
  • leetcode刷题-归纳总结
    框架思维124.求⼆叉树中最⼤路径和后序遍历最大路径转换为为求单边最大路径105.根据前序和中序遍历构造二叉树前序遍历,找到根节点构建root,得到左右子树区间,左右子树递归构建注意:1.终止条件2.构建unordered_map230.寻找⼆叉搜索树中的第k⼩的元素⼆叉搜索树即左支树所有......
  • LeetCode 419. 甲板上的战舰(深度优先搜索dfs、数组)
    419.甲板上的战舰思路:方法一,深度优先搜索dfs,遇到‘X’,就dfs一次,并在board中将其变为‘.’。classSolution{public:voiddfs(intx,inty,vector<vector<char>>&board){if(board[x][y]!='X')return;board[x][y]='.';if(x+1......
  • Leetcode419 甲板上的战舰
    最近以来,我在力扣上坚持完成每天一题,今天系统推的题目为《甲板上的战舰》,在此记录一下。题目描述如下:给你一个大小为mxn的矩阵board表示甲板,其中,每个单元格可以是一艘战舰'X'或者是一个空位'.',返回在甲板board上放置的战舰的数量。战舰只能水平或者垂直放置在......
  • 华为OD刷题C卷 - 每日刷题 22(计算面积、绘图机器,信道分配)
    1、(计算面积、绘图机器):这段代码是解决“计算面积、绘图机器”的问题。它提供了一个Java类Main,其中包含main方法,用于计算绘图机器按照给定指令绘制直线所形成的图形面积。main方法首先读取指令数量n和横坐标终点值end_X。然后,初始化面积和area为0,以及上一个点的坐标last_X......
  • 华为OD刷题C卷 - 每日刷题 23(提取字符串中的最长表达式,模拟目录管理功能 - 完整实现)
    1、提取字符串中的最长表达式目标是从一个给定的字符串中提取出最长的合法简单数学表达式,并计算该表达式的值。如果存在多个同样长度的合法表达式,则选择第一个出现的表达式进行计算。简单数学表达式的规则:只包含0-9的数字和+、-、*三种运算符。所有数字的计算结果不超过......
  • LeetCode 409 Longest Palindrome All In One
    LeetCode409LongestPalindromeAllInOneLeetCode409最长回文算法题解Solutions//MapfunctionlongestPalindrome(s:string):number{constmap=newMap();letlen=0;for(leti=0;i<s.length;i++){if(map.has(s[i])){//配对,消元......
  • LeetCode 算法:缺失的第一个正数c++
    原题链接......
  • Q25 LeetCode49 字母异位词分组
    难好好看看  1classSolution{2publicList<List<String>>groupAnagrams(String[]strs){3if(strs==null||strs.length==0)4returnnewArrayList<>();5//map中key存储的是字符串中字母排序后新的字符串6Map<Stri......