Leetcode 1268 搜索推荐系统

题目信息

LeetoCode地址: 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目理解

这道题的题意不难理解,在我们使用搜索引擎的每一天都会遇到,不需要输入完整的关键词,哪怕仅仅只输入一个字,搜索引擎就会自动返回若干以这个字开头的若干查询结果,比如最近爆火的《繁花》电视剧

该题目是搜索引擎的极致简化版,每个字符都是a-z这26个小写字母。

如果你做过Trie 树相关的题目,很容就能联想到该题目可以以同样的方式求解,当我们建立好Trie 树之后,只要按照searchWord的每个字符进行逐个匹配直到最后一个字符,这时在按字典序查找最多3个以该字符为前缀的终止字符串。

这里就不对过程详细展开了,需要的同学可以回顾下面两篇文章。

实现Trie 字典树:CSDN

添加与搜索单词:CSDN

Trie树 写法

详细过程就不论述了,需要注意的是,在从第1个字符逐次递增一个字符进行搜索时,每一次都可以从上一次结尾的Trie 节点开始,而无需每次都从第0个字符开始,以节省时间。

在products树组长度为n,每个product字符串平均长度为m,searchWord字符串长度为s的情况下:

搜索 时间复杂度: O(s *26^m),在每一次遍历节点是,理论最坏qingdfs最多会调用product字符串长度层,每次都会遍历26个字符。

额外空间复杂度:O(n*m), 用于存储Trie树节点。

Trie root;public List<List<String>> suggestedProducts(String[] products, String searchWord) {root = new Trie();for (String product : products) {addWord(product);}List<List<String>> result = new ArrayList<>();Trie lastEndTrie = root;for (int i = 0; i< searchWord.length(); i++) {List<String> current =  new ArrayList<>();lastEndTrie = search(lastEndTrie, searchWord, i, current);result.add(current);}return result;}public Trie search(Trie lastEndTrie, String word, int index, List<String> list) {if (lastEndTrie == null) {return null;}int indexOfChar = word.charAt(index) - 'a';Trie next = lastEndTrie.nextList[indexOfChar];if (next != null) {lastEndTrie = next;} else {return null;}dfs(lastEndTrie, list);return lastEndTrie;}public void addWord(String word) {Trie current = root;for (char c : word.toCharArray()) {if (current.nextList[c-'a'] != null) {current = current.nextList[c-'a'];} else {Trie next = new Trie();current.nextList[c-'a'] = next;current = next;}}current.value = word;current.end = true;}private void dfs(Trie current, List<String> list) {if (list.size() == 3 || current == null) {return;}if (current.end) {list.add(current.value);}for (Trie trie : current.nextList) {if (trie != null) {dfs(trie, list);}}}class Trie {boolean end;String value;Trie[] nextList;public Trie() {this.end = false;this.nextList = new Trie[26];}}

排序+双指针 写法

其实当题目提到“按字典序返回最小的三个” 这样的描述时,我们就要很警觉了,因为很可能和与排序有关系。

假如我们先将products按照字典序进行排序,然后确定满足当前searchWord的product的左右下标区间,则该区间最左侧的三个元素就是题目要求的字典序最小的三个元素。

更妙的是,假设我们当前搜索匹配的字符串是searchWord的0到i字串,当我们递增i匹配0到i+1字传时,完全不需要从头确定products的左右下标,直接基于上一次遍历的下标基础上进行类似的缩小范围即可。

那么缩小范围的逻辑是什么呢?其实也是很直观的。

  • 初始来看,左下标l=0, 右下标r=products.length-1. 毫无疑问l<=r 是必须保证的
  • 其次,下标l对应的的product,其长度必须大于等于当前searchWord下标i,否则就要向右移动l. 当product[l]的第i个字符与searchWord的第i个字符不相符时,也不满足题目前缀的要求,也应该向右移动l.
  • 类似的,下标r对应的的product,其长度必须大于等于当前searchWord下标i,否则就要向左移动r. 当product[r]的第i个字符与searchWord的第i个字符不相符时,也不满足题目前缀的要求,也应该向左移动r.

当l和r位置在当前i的值下都确定之后,就可以将区间内的前三个元素放入结果集中,然后对i递增,进行下一轮的遍历,直到遍历完所有的字符。

在products树组长度为n,每个product字符串平均长度为m,searchWord字符串长度为s的情况下:

搜索 时间复杂度: O(n),l向右移动,r向左移动,直到相遇为止,最多会移动products的长度那么多步。

额外空间复杂度:O(1),由于所有操作都在原树组上进行,我们只需要几个下标变量,仅需要常数规模的空间存储。

public List<List<String>> suggestedProducts(String[] products, String searchWord) {Arrays.sort(products);int l = 0, r = products.length-1;List<List<String>> result = new ArrayList<>();for (int i = 0; i < searchWord.length(); i++) {while (l < r && (products[l].length() <= i || products[l].charAt(i) != searchWord.charAt(i))) {l++;}while (l < r && (products[r].length() <= i || products[r].charAt(i) != searchWord.charAt(i))) {r--;}List<String> temp = new ArrayList<>();for (int ii = l; ii<=r && ii+3 <=r; ii++) {temp.add(products[ii]);}result.add(temp);}return result;}

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

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

相关文章

前端框架 - htmx

前端框架很多&#xff0c;但是很多时候只是想要一个简单的功能&#xff0c;如点击一个按钮&#xff0c;然后发送一个请求&#xff0c;然后更新页面的某个部分&#xff0c;这个时候&#xff0c;就不需要复杂的前端框架&#xff0c;只需要一个简单的工具就可以了&#xff0c;这个…

【ArcGIS微课1000例】0095:横向图例制作案例教程

文章目录 一、加载数据二、高程分级显示三、横向图例四、注意事项一、加载数据 为了便于直观演示,本实验加载一个栅格数据(配套实验数据包中的0095.rar)并进行分级显示,效果如下: 二、高程分级显示 双击dem数据图层,打开栅格数据的【图层属性】对话框,切换到【符号系统…

最长公共子串的问题(正常方法和矩阵法,动态规划)

题目&#xff1a; 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符…

DAY31:贪心算法入门455、53、376

理论基础 贪心算法的基本思路是通过局部最优从而达到全局最优&#xff0c;但是有时候局部最优并不一定导致全局最优&#xff0c;这样就需要动态规划的方法。但一部分题目是能通过贪心得到的。贪心的证明一般用到数学归纳法和反证法。在实际的问题中&#xff0c;没有统一的代码…

Java通过模板替换实现excel的传参填写

以模板为例子 将上面$转义的内容替换即可 package com.gxuwz.zjh.util;import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.*; import java.util.HashMap; import java.util.Map; import java.io.IOException; impor…

linux系统nginx工具性能优化

nginx性能优化 nginx性能优化当前系统结构瓶颈了解业务模式性能与安全系统与nginx性能优化文件句柄系统全局性修改进程局部性修改cpu的亲和配置配置worker_processes nginx通用配置优化cpu绑定nginx 隐藏版本nginx 修改上传文件大小nginx 启用压缩传输 nginx性能优化 当前系统…

【算法题】76. 最小覆盖子串

题目 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 "" 。 注意&#xff1a; 对于 t 中重复字符&#xff0c;我们寻找的子字符串中该字符数量必须不少于 t 中该字符数…

conda多虚拟环境的搭建与切换

在 Python 开发中&#xff0c;很多时候我们希望每个应用有一个独立的 Python 环境&#xff08;比如应用 1 需要用到 TensorFlow 1.X&#xff0c;而应用 2 使用 TensorFlow 2.0&#xff09;。这时&#xff0c;Conda 虚拟环境即可为一个应用创建一套 “隔离” 的 Python 运行环境…

copilot和chatGPT的区别分析

Copilot是一个基于人工智能的代码提示工具&#xff0c;由GitHub和人工智能公司合作开发。它可以利用机器学习技术和大量训练数据生成高质量的代码&#xff0c;提高开发者的编码效率。Copilot的工作原理是基于自然语言处理、机器学习和深度神经网络技术&#xff0c;以及大规模实…

uni-app学习与快速上手

文章目录 一、uni-app二、学习与快速上手三、案例四、常见问题五、热门文章 一、uni-app uni-app是一种基于Vue.js开发框架的跨平台应用开发框架&#xff0c;可以用于同时开发iOS、Android、H5和小程序等多个平台的应用。uni-app的设计理念是一套代码可以编译到多个平台运行&a…

CentOS 7 下安装 Docker 及配置阿里云加速服务

一、系统要求与环境准备 在 CentOS 7 系统中安装 Docker 前&#xff0c;请确保您的内核版本满足最低要求&#xff08;Docker 要求内核版本至少为 3.10 或更高&#xff09;。运行以下命令检查当前内核版本&#xff1a; uname -r若内核版本符合条件&#xff0c;接着更新系统至最…

这些SQL你练习过吗?(网友提供的SQL)

行转列SQL练习 题目 把图1转换成图2结果展示 图1 CREATE TABLE TEST_TB_GRADE (ID int(10) NOT NULL AUTO_INCREMENT,USER_NAME varchar(20) DEFAULT NULL,COURSE varchar(20) DEFAULT NULL,SCORE float DEFAULT 0,PRIMARY KEY (ID) )insert into TEST_TB_GRADE(USER_NAME, CO…

STM32单片机项目之多功能智能小车硬件设计

基于STM32单片机多功能智能小车功能说明&#xff1a; TFTLCD显示按键LVGL&#xff08;菜单、小车工作模式选择、设置&#xff09;手机蓝牙遥控模式射频手柄遥控模式5路红外寻迹模式超声波避障模式语音播报低功耗控制 硬件原理图设计 单片机最小系统&#xff1a; 由于要使用…

通信技术的OSI协议层

通信协议层是网络通信虫的重要组成部分.它定义了在网络进行数据传输时所需遵循的规则和流程。而OSI参考模型是由国际标准化组织提出的概念模型&#xff0c;可以为各种计算机互连构成网络提供标准框架。在用 OSI模型实现融媒体平台网络组建的过程中&#xff0c;相关主体需要认识…

滴滴开源小程序框架 Mpx 新特性:局部运行时能力增强

Mpx 是滴滴开源的一款增强型跨端小程序框架&#xff0c;自 2018 年立项开源以来如今已经进入第六个年头&#xff0c;在这六年间&#xff0c;Mpx 根植于业务&#xff0c;与业务共同成长&#xff0c;针对小程序业务开发中遇到的各类痛点问题提出了解决方案&#xff0c;并在滴滴内…

NVIDIA Isaac ROS - 入门教程(一)

系列文章目录 前言 欢迎访问 Isaac ROS&#xff0c;这是一套硬件加速、高性能、低延迟的 ROS 2 软件包&#xff0c;用于制造自主机器人&#xff0c;充分利用 Jetson 和其他英伟达平台的强大功能。 查看入门指南&#xff0c;开始使用 Isaac ROS。设置 Isaac ROS Buildfarm&…

如何让思维系统化,拥有「自己的想法」?

先思考一个问题&#xff1a; 如果外星人来访地球&#xff0c;你觉得他们更有可能是善意的&#xff0c;还是恶意的&#xff1f; 你的反应是什么&#xff0c;会如何切入思考&#xff1f; 一般人可能会这样回答&#xff1a; 当然是恶意的&#xff0c;因为要争夺资源啊&#xff0c;…

前端工程化之:webpack1-3(模块化兼容性)

一、模块化兼容性 由于 webpack 同时支持 CommonJs 和 ES6 module &#xff0c;因此需要理解它们互操作时 webpack 是如何处理的。 二、同模块化标准 如果导出和导入使用的是同一种模块化标准&#xff0c;打包后的效果和之前所说的模块化没有任何差异。 CommonJS&#xff…

25考研政治备考计划

各位小伙伴大家好&#xff0c;今天给大家分享的是25考研政治复习备考计划。 政治没有基础阶段&#xff0c;直接就是强化&#xff0c;强化的内容也就是听课&#xff0c;刷题。 【时间安排】 *7-9月中 徐涛老师或腿姐强化课&#xff0c;推荐刷肖1000 *9月中-10月中 背腿姐的背…

ELK+Filebeat 部署实验

Filebeat是轻量级的开源日志文件数据搜集器。通常在需要采集数据的客户端安装 Filebeat&#xff0c;并指定目录与日志格式&#xff0c;Filebeat 就能快速收集数据&#xff0c;并发送给 logstash 进行解析&#xff0c;或是直接发给 Elasticsearch 存储&#xff0c;性能上相比运行…