30-判断子序列

给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace""abcde"的一个子序列,而"aec"不是)。

进阶:

如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

方法一:双指针法

这是最直观的方法,通过两个指针分别遍历字符串 s 和 t,逐个比较字符。

// 判断 s 是否为 t 的子序列
function isSubsequence(s: string, t: string): boolean {let i = 0; // 指向 s 的指针let j = 0; // 指向 t 的指针while (i < s.length && j < t.length) {if (s[i] === t[j]) {i++;}j++;}return i === s.length;
}// 测试示例
let s1 = "ace";
let t1 = "abcde";
console.log(isSubsequence(s1, t1)); // 输出 truelet s2 = "aec";
let t2 = "abcde";
console.log(isSubsequence(s2, t2)); // 输出 false
复杂度分析
  • 时间复杂度:(O(n)),其中 n 是字符串 t 的长度,因为只需要遍历一次字符串 t
  • 空间复杂度:(O(1)),只使用了常数级的额外空间。

方法二:递归法

通过递归的方式来判断 s 是否为 t 的子序列。

function isSubsequenceRecursive(s: string, t: string): boolean {if (s.length === 0) {return true;}if (t.length === 0) {return false;}if (s[0] === t[0]) {return isSubsequenceRecursive(s.slice(1), t.slice(1));}return isSubsequenceRecursive(s, t.slice(1));
}// 测试示例
let s3 = "ace";
let t3 = "abcde";
console.log(isSubsequenceRecursive(s3, t3)); // 输出 truelet s4 = "aec";
let t4 = "abcde";
console.log(isSubsequenceRecursive(s4, t4)); // 输出 false
复杂度分析
  • 时间复杂度:(O(n)),其中 n 是字符串 t 的长度。在最坏情况下,需要递归 n 次。
  • 空间复杂度:(O(n)),主要是递归调用栈的空间开销。

方法三:动态规划法

使用动态规划来解决这个问题,通过构建一个二维数组来记录子问题的解。

function isSubsequenceDP(s: string, t: string): boolean {let m = s.length;let n = t.length;let dp: boolean[][] = new Array(m + 1).fill(false).map(() => new Array(n + 1).fill(false));// 初始化for (let j = 0; j <= n; j++) {dp[0][j] = true;}for (let i = 1; i <= m; i++) {for (let j = 1; j <= n; j++) {if (s[i - 1] === t[j - 1]) {dp[i][j] = dp[i - 1][j - 1];} else {dp[i][j] = dp[i][j - 1];}}}return dp[m][n];
}// 测试示例
let s5 = "ace";
let t5 = "abcde";
console.log(isSubsequenceDP(s5, t5)); // 输出 truelet s6 = "aec";
let t6 = "abcde";
console.log(isSubsequenceDP(s6, t6)); // 输出 false
复杂度分析
  • 时间复杂度:(O(m * n)),其中 m 是字符串 s 的长度,n 是字符串 t 的长度。需要填充一个 (m+1) 行 (n+1) 列的二维数组。
  • 空间复杂度:(O(m * n)),主要是二维数组的空间开销。

进阶:处理大量输入的情况

当有大量输入的 S((S_1, S_2, ... , S_k),(k >= 10) 亿)需要依次检查它们是否为 T 的子序列时,可以采用预处理 T 的方法。具体思路是记录 T 中每个字符出现的所有位置,然后对于每个 S 中的字符,使用二分查找来找到该字符在 T 中合适的位置。

import { bisectLeft } from '@ohos.bisect';function isSubsequenceAdvanced(s: string, t: string): boolean {// 预处理 t,记录每个字符出现的所有位置let charIndexes: Map<string, number[]> = new Map();for (let i = 0; i < t.length; i++) {let char = t[i];if (!charIndexes.has(char)) {charIndexes.set(char, []);}charIndexes.get(char)!.push(i);}let prevIndex = -1;for (let char of s) {if (!charIndexes.has(char)) {return false;}let indexList = charIndexes.get(char)!;let index = bisectLeft(indexList, prevIndex + 1);if (index === indexList.length) {return false;}prevIndex = indexList[index];}return true;
}// 测试示例
let s7 = "ace";
let t7 = "abcde";
console.log(isSubsequenceAdvanced(s7, t7)); // 输出 truelet s8 = "aec";
let t8 = "abcde";
console.log(isSubsequenceAdvanced(s8, t8)); // 输出 false
复杂度分析
  • 预处理时间复杂度:(O(m)),其中 m 是字符串 t 的长度。需要遍历一次字符串 t 来记录每个字符出现的位置。
  • 每个 S 的检查时间复杂度:(O(k log m)),其中 k 是字符串 S 的长度,m 是字符串 t 的长度。对于 S 中的每个字符,需要进行一次二分查找。
  • 空间复杂度:(O(m)),主要用于存储每个字符出现的位置。

通过这种方式,可以在处理大量输入时提高效率。

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

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

相关文章

matlab常见的配图代码实现1

1. 折线图 x linspace(0, 10, 100); y1 sin(x);y2 cos(x); figure; plot(x, y1, -o, LineWidth, 2, MarkerSize, 6, MarkerFaceColor, b); hold on;plot(x, y2, -s, LineWidth, 2, MarkerSize, 6, MarkerFaceColor, r); title(折线图); xlabel(X轴); ylabel(Y轴); legend(s…

【汇编语言】单片机程序执行过程

一、任务需求 指示灯LED4闪烁&#xff0c;亮0.5秒&#xff0c;灭0.5秒&#xff0c;无限循环 二、针对硬件的编程 1、确定原理图2、确定硬件的物理关系 三、设计步骤 1.用自己的语言描述工作流程 1.1指示灯LED4亮1.2延时0.5秒1.3指示灯LED4灭1.4延时0.5秒1.5跳转到1.1步 …

从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(十二) socketio 消息处理

1.后端 在message.controller.js中 在sendMessage方法中 每当我们发送消息 需要socketio把这个消息转发给 接收人 加入转发逻辑 // 把消息发给指定的用户的socket const receiverSocketId getReceiverSocketId(receiverId); if(receiverSocketId) { io.to(receiverSocket…

【大模型】WPS 接入 DeepSeek-R1详解,打造全能AI办公助手

目录 一、前言 二、WPS接入AI工具优势​​​​​​​ 三、WPS接入AI工具两种方式 3.1 手动配置的方式 3.2 Office AI助手 四、WPS手动配置方式接入AI大模型 4.1 安装VBA插件 4.1.1 下载VBA插件并安装 4.2 配置WPS 4.3 WPS集成VB 4.4 AI助手效果测试 4.5 配置模板文…

SmolVLM2 - 将视频理解带到每个设备

本文翻译整理自&#xff1a;SmolVLM2: Bringing Video Understanding to Every Device https://huggingface.co/blog/smolvlm2 文章目录 TL;DR: SmolVLM 现在可以观看 &#x1f4fa; 并拥有更好的视觉理解一、关于 SmolVLM2二、 技术细节1、SmolVLM2 2.2B: 我们新的视觉和视频明…

Cocos Creator Shader入门实战(三):CCEffect参数配置讲解

引擎版本&#xff1a;3.8.5 您好&#xff0c;我是鹤九日&#xff01; 回顾 稍微回顾下前面两篇博客讲解的内容&#xff1a; 一、Cocos渲染效果的实现需要Material材质和Effect资源的互相配合。 二、Effect资源负责Shader片段的编写和属性配置&#xff0c;Material材质负责对E…

计算机毕业设计:公司烤箱配件质量信息追溯系统

超级管理员表创建语句如下&#xff1a; 公司烤箱配件质量信息追溯系统mysql数据库创建语句公司烤箱配件质量信息追溯系统oracle数据库创建语句公司烤箱配件质量信息追溯系统sqlserver数据库创建语句公司烤箱配件质量信息追溯系统springspringMVCmybatis框架对象(javaBean,pojo…

【移动WEB开发】rem适配布局

目录 1. rem基础 2.媒体查询 2.1 语法规范 2.2 媒体查询rem 2.3 引入资源&#xff08;理解&#xff09; 3. less基础 3.1 维护css的弊端 3.2 less介绍 3.3 less变量 3.4 less编译 3.5 less嵌套 3.6 less运算 4. rem适配方案 4.1 rem实际开发 4.2 技术使用 4.3 …

Java后端高频面经——计算机网络

TCP/IP四层模型&#xff1f;输入一个网址后发生了什么&#xff0c;以百度为例&#xff1f;&#xff08;美团&#xff09; &#xff08;1&#xff09;四层模型 应用层&#xff1a;支持 HTTP、SMTP 等最终用户进程传输层&#xff1a;处理主机到主机的通信&#xff08;TCP、UDP&am…

DeepSeek R1-32B医疗大模型的完整微调实战分析(全码版)

DeepSeek R1-32B微调实战指南 ├── 1. 环境准备 │ ├── 1.1 硬件配置 │ │ ├─ 全参数微调:4*A100 80GB │ │ └─ LoRA微调:单卡24GB │ ├── 1.2 软件依赖 │ │ ├─ PyTorch 2.1.2+CUDA │ │ └─ Unsloth/ColossalAI │ └── 1.3 模…

《Python实战进阶》No16: Plotly 交互式图表制作指南

No16: Plotly 交互式图表制作指南 Plotly是一款用来做数据分析和可视化的在线平台&#xff0c;功能真的是非常强大&#xff0c;它主要有以下特点&#xff1a; 图形多样化&#xff1a;在线绘制多种图形&#xff0c;比如柱状图、饼图、直方图、饼图、气泡图、桑基图、股票图、旭…

贪心算法--

1.柠檬水找零 link:860. 柠檬水找零 - 力扣&#xff08;LeetCode&#xff09; code class Solution { public:bool lemonadeChange(vector<int>& bills) {// 贪心算法&#xff0c; 优先花出大面额bill&#xff0c; 尽可能保护小面额billint five 0, ten 0;// 不…

基于策略模式的智能提示语生成器设计与实现——以Tkinter GUI开发为例

基于策略模式的智能提示语生成器设计与实现——以Tkinter GUI开发为例 一、引言&#xff1a;智能化时代的提示工程工具 在人工智能技术广泛应用的时代背景下&#xff0c;如何与AI模型进行有效交互已成为关键技能。本文介绍的"AI任务需求与提示语策略生成器"正是基于…

【MySQL】(4) 表的操作

一、创建表 语法&#xff1a; 示例&#xff1a; 生成的数据目录下的文件&#xff1a; 二、查看表结构 三、修改表 语法&#xff1a; 另一种改表名语法&#xff1a;rename table old_name1 to new_name1, old_name2 to new_name2; 示例&#xff1a; 四、删除表 语法&#xf…

基于STM32物联网水质监测系统的设计与实现/基于STM32的水产养殖云监控系统设计

1. 系统方案介绍 随着水质污染问题的日益严峻&#xff0c;实时监测水质变得尤为重要。水质监测系统能够通过采集水体中的各种数据&#xff0c;及时发现水质问题&#xff0c;保障饮用水安全。本文将介绍一款基于STM32单片机的物联网水质监测系统&#xff0c;该系统采用了ESP826…

装饰器模式--RequestWrapper、请求流request无法被重复读取

目录 前言一、场景二、原因分析三、解决四、更多 前言 曾经遇见这么一段代码&#xff0c;能看出来是把request又重新包装了一下&#xff0c;核心信息都不会改变 后面了解到这叫 装饰器模式&#xff08;Decorator Pattern&#xff09; &#xff1a;也称为包装模式(Wrapper Pat…

IO多路复用实现并发服务器

一.select函数 select 的调用注意事项 在使用 select 函数时&#xff0c;需要注意以下几个关键点&#xff1a; 1. 参数的修改与拷贝 readfds 等参数是结果参数 &#xff1a; select 函数会直接修改传入的 fd_set&#xff08;如 readfds、writefds 和 exceptfds&#xf…

解决火绒启动时,报安全服务异常,无法保障计算机安全

1.找到控制面板-安全和维护-更改用户账户控制设置 重启启动电脑解决。

【Docker】容器安全之非root用户运行

【Docker】容器安全之非root用户运行 1. 场景2. 原 Dockerfile 内容3. 整改结果4. 非 root 用户带来的潜在问题4.1 文件夹读写权限异常4.2 验证文件夹权限 1. 场景 最近有个项目要交付&#xff0c;第三方测试对项目源码扫描后发现一个问题&#xff0c;服务的 Dockerfile 都未指…

3.9[A]csd

在传统CPU中心架构中&#xff0c;中央处理器通过内存访问外部存储器&#xff0c;而数据必须经过网络接口卡才能到达外部存储器。这种架构存在集中式计算、DRAM带宽和容量挑战、大量数据移动&#xff08;服务器内和网络&#xff09;以及固定计算导致工作负载容量增长等问题。 而…