单词搜索 II

news2024/11/24 4:55:49

题目链接

单词搜索 II

题目描述


注意点

  • board[i][j] 是一个小写英文字母
  • words[i] 由小写英文字母组成
  • words 中的所有字符串互不相同
  • 同一个单元格内的字母在一个单词中不允许被重复使用

解答思路

  • 要想找到一个完整的单词,首先想到的是深度优先遍历,如果想要时间复杂度更低,很容易想到剪枝,剪枝的节点在于如果某个字符串在words中没有一个单词的前缀与该字符串重合(注意不是words中不包含该字符串),所以还要用到前缀树的知识,可以参考前缀树,所以本题的主要思路为深度优先遍历+剪枝+前缀树
  • 第一步要完成的是前缀树的构建,因为本题中所有单词都是由小写字母组成,所以前缀树的子树可以由大小为26的TrieNode数组构成;第二步是遍历整个board数组,将任意位置作为起点;第三步是从起点开始深度优先遍历,在搜索单词的期间判断其是否在前缀树中,如果不存在则直接剪枝,如果存在则需要判断其是否是单词并重复进行第三步进行深度优先遍历(注意,在此期间,需要对该位置是否遍历进行回溯)

代码

class Solution {
    public List<String> findWords(char[][] board, String[] words) {
        List<String> res = new ArrayList<>();
        int row = board.length;
        int col = board[0].length;
        // 存储board[i][j]是否已经访问过
        boolean[][] visited = new boolean[row][col];
        // 构建前缀树
        Trie trie = new Trie();
        for (String word : words) {
            trie.insert(word);
        }
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                dfs(board, words, visited, trie.root, res, i, j);
            }
        }
        return res;
    }

    public void dfs(char[][] board, String[] words, boolean[][] visited, TrieNode trieNode, List<String> res, int i, int j) {
        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length) {
            return;
        }
        if (visited[i][j]) {
            return;
        }
        trieNode = trieNode.childTrie[board[i][j] - 'a'];
        // 在前缀树中未找到该前缀
        if (trieNode == null) {
            return;
        }
        if (trieNode.word != null && !"".equals(trieNode.word)) {
            res.add(trieNode.word);
            // 该单词已经加入到结果集中,删除防止重复添加
            trieNode.word = null;
        }
        visited[i][j] = true;
        // 上下左右四个方向深度搜索单词
        dfs(board, words, visited, trieNode, res, i - 1, j);
        dfs(board, words, visited, trieNode, res, i + 1, j);
        dfs(board, words, visited, trieNode, res, i, j - 1);
        dfs(board, words, visited, trieNode, res, i, j + 1);
        // 回溯
        visited[i][j] = false;
    }
}

class TrieNode {
    String word;
    TrieNode[] childTrie = new TrieNode[26];
}

class Trie {
    TrieNode root = new TrieNode();
    public void insert(String word) {
        TrieNode currTrie = root;
        for (char c : word.toCharArray()) {
            if (currTrie.childTrie[c - 'a'] == null) {
                currTrie.childTrie[c - 'a'] = new TrieNode();
            }
            currTrie = currTrie.childTrie[c - 'a'];
        }
        currTrie.word = word;
    }
}

关键点

  • 前缀树的概念及构建过程
  • 深度优先遍历的思想
  • 怎样利用前缀树优化对空间的利用及减少遍历次数(前缀树的叶子节点存储整个单词)
  • 剪枝节省时间的三个节点:一是board[i]j[]已经遍历过进行剪枝,二是字符串不在前缀树中进行剪枝,三是对已经添加到结果集中的某个单词对应前缀树中存储的该单词信息进行剪枝

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1320115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

patchless amsi学习(中)

DR7 DR7被称为“调试控制寄存器”&#xff0c;允许对每个硬件断点进行精细控制。其中&#xff0c;前8位控制是否启用了特定的硬件断点。偶数位&#xff08;0、2、4、6&#xff09;称为L0-L3&#xff0c;在本地启用了断点&#xff0c;这意味着仅在当前任务中检测到断点异常时才…

RocketMQ 顺序消息收发实践

目录 概述局部有序创建 Topic配置代码测试 结束 概述 顺序消息 全局有序&#xff1a;适用于性能不是特别高的场景&#xff0c;但是又要求消息又严格一致的概念。局部有序&#xff1a;适用于性能要求高的场景&#xff0c;想办法通过在设计层面处理有序的消息尽量发送至同一个 T…

qt QFile文件操作处理,QFileInfo文件信息读取的简单介绍

QFile类用于文件操作,对文件进行读写操作,可读写文件,二进制文件和qt资源文件.处理文本文件和二进制文件可使用QTextStream类和QDataStream类,处理临时文件可以使用QTemporary,获取文件信息可以使用QFileInfo,处理目录可以使用QDir,监视文件和目录变化可以使用QFileSystemWatch…

整合SSH(Spring+Struts+Hibernate)

0.前言, 由于工作需要故来学习SSH的整合,structs其实相当于(把view和controller结合起来,没有像现在的前后端分离,请求会发送给Action处理,在structs.xml映射地址和类) Hibernate(就是处理数据库的,几乎自动化,也可以写sql语句) Struts&#xff1a;Struts 是一个基于 MVC&#…

【Python】计算一年内的总天数(还有跨年日期)

花了一段时间才找到Python中求一年中总日数&#xff08;total day of the Year&#xff09;的格式代码&#xff0c;所以也把计算方法记录下来。 基本 首先&#xff0c;简单地找出一年中的总天数&#xff0c; strftime() 和 strptime() 的格式代码是 %j ↓看这里 使用 strft…

算法基础之Prim算法求最小生成树

Prim算法求最小生成树 核心思想&#xff1a;Prim 算法 类似于dijkstra算法 更新距离时改为到**集合(生成树)**的距离 最小生成树长这样 每次迭代放一个最近(有边)点&#xff0c;一条最短边进生成树 #include <cstring>#include <iostream>#include <algori…

08-Event Sources和Sink架构

1 PingSource -> Kubernetes Service Sink 架构模型 示例1 部署一个kubernetes类型的sink&#xff0c;这里面还是以event-display为例&#xff0c;下面是资源清单 --- apiVersion: apps/v1 kind: Deployment metadata:name: event-display spec:replicas: 1selector:matc…

Axie Infinity 之后,Ronin 的潜力何在?

作者&#xff1a;stellafootprint.network 数据来源&#xff1a;Ronin Dashboard 备受欢迎的 Web3 游戏 Pixels 在 2023 年 10 月下旬从 Polygon 迁移到了专为游戏设计的区块链 Ronin。Pixels 此前作为 Polygon 上活跃用户&#xff08;钱包数量&#xff09;最多的 Web3 游戏&…

【重点】【DFS】【子集】78.子集

题目 法1&#xff1a;DFS 必须掌握的方法&#xff01;&#xff01;&#xff01; 我们也可以用递归来实现子集枚举。 假设我们需要找到一个长度为 nnn 的序列 aaa 的所有子序列&#xff0c;代码框架是这样的&#xff1a; void dfs(int cur, int n, LinkedList<Integer>…

HTML5+CSS3小实例:3D发光切换按钮效果

目录 一、运行效果 图片效果 二、项目概述 三、开发环境 四、实现步骤及代码 1.创建空文件夹 2.完成页面内容 3.完成css样式 五、项目总结 六、源码获取 一、运行效果 图片效果 二、项目概述 该项目是一个基于HTML和CSS的动态小猫动画。通过使用CSS样式和动画效果…

开源支付项目,还有强大的聚合支付项目,值得借鉴学习,收藏备用

开源支付项目,还有强大的聚合支付项目,值得借鉴学习,收藏备用 自学编程之道2023-03-18 14:26 移动支付随处可见,以前都是微信、支付宝分别各一个收款码,二维码多了之后就不好管理了,随着支付方式的增多,现在基本上都用聚合支付,多种支付方式,一码搞定。针对支付及聚…

Linux常用网络指令

网络参数设定使用的指令 手动/自动设定与启动/关闭 IP 参数&#xff1a;ifconfig, ifup, ifdown ifconfig ifconfig常用于修改网络配置以及查看网络参数的指令 [rootwww ~]# ifconfig {interface} {up|down} < 观察与启动接口 [rootwww ~]# ifconfig interface {options…

项目管理:产品经理如何保障项目按时完成

一个项目的成功要考虑多方因素&#xff0c;即使经过了精细的策划&#xff0c;但是在项目推进过程中也会遇到各种问题。 产品经理的任务就不仅仅在于完成产品策划&#xff0c;还需要承担项目管理工作&#xff0c;跟进项目进度&#xff0c;必要时还得出面协调、解决冲突&#x…

猜数字小游戏(猜错了会关机推荐让室友帮你玩)

前言 今天来带大家写一个简易的猜数字小游戏&#xff0c;如果连着猜错n次&#xff08;自己设定&#xff09;就会导致电脑关机&#xff0c;还在等什么呢&#xff1f;赶紧学会咯&#xff0c;发给你的室友让他帮你玩吧&#xff01; 正文 随机数的生成 首先我们还要学会如何创建随…

Windows10 如何开机自动启动redis

前言 当我们在Windows 10上使用Redis时&#xff0c;通常希望能够使Redis服务在系统启动时自动启动&#xff0c;以便我们无需手动介入就能够方便地访问和管理数据。在这个过程中&#xff0c;我们将通过下载、安装和配置Redis为Windows服务的方式&#xff0c;使其成为系统的一部分…

python与机器学习4,激活函数

目录 1 激活函数1: 单位阶跃函数 1.1 函数形式 1.2 函数图形 1.3 函数特点 1.4 代码实现这个 单位阶跃函数 2 激活函数2 sigmoid函数 2.1 函数形式 2.2 函数图形 2.3 函数特点 2.3.1 是一个连续函数&#xff0c;且是一个渐变的曲线 2.3.2 是连续区间的[0,1] , 可以…

JVM基础扫盲

什么是JVM JVM是Java设计者用于屏蔽多平台差异&#xff0c;基于操作系统之上的一个"小型虚拟机"&#xff0c;正是因为JVM的存在&#xff0c;使得Java应用程序运行时不需要关注底层操作系统的差异。使得Java程序编译只需编译一次&#xff0c;在任何操作系统都可以以相…

定制 Electron 窗口标题栏

Electron 是一款流行的桌面应用开发框架&#xff0c;基于 Web 技术构建&#xff0c;提供了强大的跨平台能力。在开发过程中&#xff0c;经常需要定制窗口标题栏以创造独特的用户体验。 1. 完全隐藏默认标题栏 有时候&#xff0c;我们希望创建一个自定义的标题栏&#xff0c;完…

光伏收益计算工具:实现可持续能源投资的决策支持

随着全球能源结构的转型&#xff0c;光伏发电作为主要的可再生能源之一&#xff0c;其投资前景日益光明。然而&#xff0c;光伏发电项目的投资决策需要基于准确的收益预测。因此&#xff0c;光伏收益计算工具应运而生&#xff0c;为投资者提供决策支持。 光伏收益计算工具是一种…

护肤品品牌怎么创建百度百科词条?

护肤品品牌创建百度百科词条&#xff0c;需要遵循一定的步骤和原则&#xff0c;同时保证内容的真实性和权威性。以下是伯乐网络传媒给大家分享的详细创建流程和注意事项&#xff1a; 一、准备工作 收集资料&#xff1a;首先&#xff0c;需要收集品牌的详细资料&#xff0c;包括…