华为OD机试真题---关联子串

华为OD机试中的“关联子串”题目是一个考察字符串处理和算法理解的经典问题。以下是对该题目的详细解析:

一、题目描述

给定两个字符串str1 和 str2,如果字符串 str1 中的字符,
经过排列组合后的字符串中只要有一个是 str2 的子串,
则认为 str1 是 str2 的关联子串,若不是关联子串则返回 -1
示例:
输入:

abc efghicaibii

输出:

-1

预制条件:
1.输入的字符串只包含小写字母
2.两个字符串的长度范围1~100000
3.若 str2 中有多个 str1 的组合子串,请返回第一个子串的起始位置
备注:输入字符串只包含小写,长度 1~100000

二、输入描述

输入两个字符串,分别为题目中描述的str1和str2。输入的字符串只包含小写字母,且两个字符串的长度范围在1到100000之间。

三、输出描述

如果str1是str2的关联子串,则返回子串在str2中的起始位置。如果不是关联子串,则返回-1。若str2中有多个str1的组合子串,则返回最小的起始位置。

四、解题思路

  1. 滑动窗口与字符频率匹配

    • 滑动窗口:用于遍历 str2 的所有可能的子串,这些子串的长度与 str1 相同。
    • 字符频率匹配:通过比较两个字符串的字符频率,可以快速判断一个字符串是否是另一个字符串的排列。这是因为排列仅仅是字符的顺序不同,而字符的数量和种类完全相同。
  2. 边界条件处理

    • 虽然题目已经规定了字符串的长度范围,并且确保两个字符串都是小写字母,但在实际编码中仍需注意输入验证。例如,输入可能包含多余的空格,或者输入的字符串不符合题目要求。
    • 特别要注意的是,当 str1 的长度大于 str2 时,直接返回 -1,因为不可能在较短的字符串中找到较长的字符串的排列。
  3. 性能优化

    • 使用数组记录字符频率而不是哈希表,是因为题目限制字符集为小写字母(共26个),这样可以节省空间并且提高访问速度。
    • 每次只遍历 str2 的必要部分(即从 0len2 - len1),避免了不必要的计算。

五、示例代码(Java)

import java.util.Scanner;public class AssociatedSubstring {/*** 主函数入口* 本程序用于判断第二个字符串是否是第一个字符串的排列,并输出其起始位置* @param args 命令行参数*/public static void main(String[] args) {// 创建Scanner对象,用于读取输入Scanner sc = new Scanner(System.in);// 读取一行输入,并根据空格分割成两个字符串String[] str = sc.nextLine().split(" ");// 提取分割后的字符串数组中的第一个元素String str1 = str[0];// 提取分割后的字符串数组中的第二个元素String str2 = str[1];// 计算第一个字符串的长度int len1 = str1.length();// 计算第二个字符串的长度int len2 = str2.length();// 定义目标索引,默认为-1,表示未找到int targetIndex = -1;// 遍历第二个字符串,寻找第一个字符串的排列for (int i = 0; i <= len2 - len1; i++) {// 截取当前遍历位置开始,与第一个字符串等长的子字符串String tmp = str2.substring(i, i + len1);// 判断截取的子字符串是否是第一个字符串的排列if (isPermutation(str1, tmp)) {// 如果是排列,记录起始索引targetIndex = i;// 找到后即可退出循环break;}}// 输出目标索引System.out.println(targetIndex);}/*** 判断两个字符串是否为互为排列* 排列是指两个字符串可以通过重新排列各自的字符而相互转换* 本方法通过比较两个字符串中每个字符的频率来判断它们是否为排列* * @param s1 第一个字符串,不区分大小写* @param s2 第二个字符串,不区分大小写* @return 如果s1和s2是排列关系,则返回true;否则返回false*/private static boolean isPermutation(String s1, String s2) {// 初始化两个数组,用于统计s1和s2中每个字母的出现次数int[] count1 = new int[26];int[] count2 = new int[26];// 统计s1中每个字符的频率for (char c : s1.toCharArray()) {count1[c - 'a']++;}// 统计s2中每个字符的频率for (char c : s2.toCharArray()) {count2[c - 'a']++;}// 比较两个字符频率数组for (int i = 0; i < 26; i++) {// 如果两个数组中当前位置的计数不相等,则字符串不是排列if (count1[i] != count2[i]) {return false;}}// 所有字符频率都相等,字符串是排列return true;}
}
六、示例代码详解
  • 输入处理:使用 Scanner 读取输入,并用 split 方法分割成两个字符串。这里假设输入格式严格符合题目要求,即两个字符串之间用空格分隔。
  • 滑动窗口:在 for 循环中,使用 substring 方法截取 str2 的子串,子串的长度与 str1 相同。
  • 字符频率匹配isPermutation 方法通过两个长度为26的数组记录两个字符串的字符频率,并逐项比较。如果所有字符的频率都相同,则这两个字符串是排列关系。
  • 结果输出:一旦找到匹配的子串,记录其起始位置并立即退出循环,因为题目要求返回第一个匹配子串的起始位置。
特殊情况处理
  • 空字符串:虽然题目已经排除这种情况,但理论上,如果 str1str2 为空,则可以直接返回 -1,因为空字符串不能构成任何非空字符串的排列。
  • 完全相同:如果 str1 正好是 str2 的一个子串(包括顺序相同),该算法仍然有效,因为完全相同的字符串也是排列关系的一种特殊情况。

七、运行示例解析

解析步骤

1、读取输入并分割字符串

  • Scanner 对象读取输入 abc efghicaibii。
  • 使用 split(" ") 方法将输入按空格分割成两个字符串数组 str。
  • str[0] 是 “abc”,str[1] 是 “efghicaibii”。

2、计算字符串长度

  • str1 的长度 len1 是 3。
  • str2 的长度 len2 是 11。

3、初始化目标索引

  • targetIndex 初始化为 -1,表示未找到排列。

4、遍历 str2 寻找排列

  • 循环从 i = 0 到 i = len2 - len1,即从 i = 0 到 i = 8。
  • 在每次循环中,截取 str2 中从 i 开始,长度为 len1 的子字符串 tmp,并与 str1 比较是否为排列。

5、具体遍历过程

  • i = 0 时,tmp = “efg”,调用 isPermutation(“abc”, “efg”) 返回 false。
  • i = 1 时,tmp = “fgh”,调用 isPermutation(“abc”, “fgh”) 返回 false。
  • i = 2 时,tmp = “ghi”,调用 isPermutation(“abc”, “ghi”) 返回 false。
  • i = 3 时,tmp = “hic”,调用 isPermutation(“abc”, “hic”) 返回 false。
  • i = 4 时,tmp = “ica”,调用 isPermutation(“abc”, “ica”) 返回 false。
  • i = 5 时,tmp = “cai”,调用 isPermutation(“abc”, “cai”) 返回false。
  • i = 6时,tmp = “aib”,调用 isPermutation(“abc”, “aib”) 返回false。
  • i = 7 时,tmp = “ibi”,调用 isPermutation(“abc”, “ibi”) 返回false。
  • i = 8 时,tmp = “bii”,调用 isPermutation(“abc”, “bii”) 返回false。

6、输出结果

  • 最终输出 targetIndex,即 -1。
输出
-1

八、注意事项

  1. 性能优化:由于字符串长度可能达到100000,因此需要注意算法的时间复杂度。上述代码使用了滑动窗口和字符频率匹配的方法,时间复杂度为O(n*m),其中n为str2的长度,m为str1的长度。在大多数情况下,这种方法是高效的。
  2. 边界条件:需要处理一些边界情况,如str1或str2为空字符串,或者str1的长度大于str2的长度等。这些边界情况在题目描述中通常已经明确排除。

通过以上解析和示例代码,相信你可以更好地理解并解决华为OD机试中的“关联子串”问题。

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

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

相关文章

vscode中每个打开的文件都显示在一个单独的标签页中

版本&#xff1a;1.94 实现步骤&#xff1a; 1、打开设置 File-》Preferences-》Settings 2、具体设置 2.1、在配置中搜索 workbench.editor.showTabs 设置为multiple。 2.2、在配置中搜索 workbench.editor.enablePreview 取消勾选。 根据这个功能的说明&#xff0c;在…

24.10.20(换根哈希)

星期一&#xff1a; 阴间场 cf渡劫成功&#xff0c;拿下三题&#xff0c;终于上蓝&#x1f973;&#x1f973;&#x1f973; 贴 cf round978 div2 C cf传送门 答案取到n1但初始化没到n1&#xff0c;wa了一发&#xff0c;很烦&#x1f63f;…

100. UE5 GAS RPG 显示范围魔法的攻击范围

在这一篇里&#xff0c;我们将制作一个范围魔法&#xff0c;释放魔法时&#xff0c;我们将在鼠标拾取位置绘制一个魔法光圈&#xff0c;用于显示技能释放时攻击的范围&#xff0c;然后再次点击可以释放技能。 创建贴花类 魔法范围标识的光圈&#xff0c;我们采用贴花实现&…

利用飞腾派进行OpenCV开发

实验目标&#xff1a; 完成飞腾平台OpenCV开发。 实验大纲&#xff1a; Mat数据结构加载、显示、保存图像读写像素RGB图像分离彩色图转灰度图 Mat数据结构 Mat是一个类&#xff0c;由两个数据部分组成&#xff1a;矩阵头(大小,通道,数据类型等)和数据块(像素 值)。创建示例…

SQL Server-导入和导出excel数据-注意事项

环境&#xff1a; win10&#xff0c;SQL Server 2008 R2 之前写过的放在这里&#xff1a; SqlServer_陆沙的博客-CSDN博客 https://blog.csdn.net/pxy7896/category_12704205.html 最近重启ASP.NET项目&#xff0c;在使用sql server导出和导入数据时遇到一些问题&#xff0c;特…

SDRAM控制器的设计与验证(野火学习笔记)

SDRAM发展至今已历经五代&#xff0c;具有单位存储量大、高数据带宽、读写速度快、价格相对便宜等优点。同时&#xff0c;作为内存条中不可缺少的有一部分&#xff0c;SDRAM在计算机领域也占有一席之地。 &#xff08;SDRAM的内容以及操作时序比较复杂&#xff0c;本文已经尽可…

计算机毕业设计Python+大模型知识图谱中华古诗词可视化 古诗词智能问答系统 古诗词数据分析 古诗词情感分析 PyTorch Tensorflow LSTM

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 开发技术&#xff1a; 前端…

Web前端-JavaScript书写位置

一、JavaScript介绍 1.JavaScript 是什么? 是一种运行在客户端(浏览器)的编程语言&#xff0c;实现人机交互效果。 2.作用 &#xff08;1&#xff09;网页特效(监听用户的一些行为让网页作出对应的反馈) &#xff08;2&#xff09;表单验证(针对表单数据的合法性进行判断…

大语言模型训练

大语言模型训练 1.两大问题2.并行训练2.1数据并行2.2模型并行2.3张量并行2.4混合并行 3.权重计算3.1浮点数3.2混合精度训练3.3deepspeed&#xff08;微软&#xff09;3.3.1 ZeRO3.3.2ZeRO-offload 3.3总结 4.PEFT4.1Prompt TuningPrefix-tuning4.2P-tuning & P-tuning v2 5…

sentinel dashboard分布式改造落地设计实现解释(二)-分布式discovery组件

discovery discovery负责维护app/机器资料库&#xff0c;transport健康检测&#xff0c; transport上下线处理。discovery关键是分布式存储&#xff0c;后续研究一下raft&#xff0c;其复制&#xff0c;状态机&#xff0c;快照技术&#xff0c;但个人觉得&#xff0c;discover…

DBeaver连接Hive教程

hive shell&#xff1a;通过hive shell来操作hive&#xff0c;但是至多只能存在一个hive shell&#xff0c;启动第二个会被阻塞&#xff0c;也就是说hive shell不支持并发操作。 基于JDBC等协议&#xff1a;启动hiveserver2&#xff0c;通过jdbc协议可以访问hive&#xff0c;hi…

基于SSM服装定制系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;服装类型管理&#xff0c;服装信息管理&#xff0c;服装定制管理&#xff0c;留言反馈&#xff0c;系统管理 前台账号功能包括&#xff1a;系统首页&#xff0c;个人中心&#xf…

git commit / push 报错 文件不存在

1. 错误信息 尝试使用 git restore --staged filename 取消暂存&#xff0c;但是报错 2. 解决方法 进入 当前仓库/.git文件夹内&#xff0c;删除 index.lock 文件 再执行 git restore --staged filename 等操作。

通过无线路由器连接三菱PLC的设置方法

1.首先设置无线路由器上网方式为DHCP&#xff08;自动获取IP地址&#xff09;。点击保存&#xff0c;然后点击更多功能 2.再点击网络设置-局域网&#xff0c;勾选DHCP服务器&#xff0c;此功能的作用是对局域网内所有设备分配IP地址。 然后保存&#xff1b; 3.再点击系统设置…

Git极速入门

git初始化 git -v git config --global user.name "" git config --global user.email "" git config --global credential.helper store git config --global --list省略(Local) 本地配置&#xff0c;只对本地仓库有效–global 全局配置&#xff0c;所有…

云计算实验1——基于VirtualBox的Ubuntu安装和配置

实验步骤 1、VirtualBox的安装 本实验使用VirtualBox-7.0.10 进行演示。对于安装包&#xff0c;大家可以前往 VirtualBox官网下载页面(https :/ / www. virtualbox.org/wiki/Downloads)下载其7.0版本安装包进行安装&#xff0c;或者直接使用QQ群的安装包VirtualBox-7.0.10-15…

给定一个正整数n随机生成n个字节即生成2n个十六进制数将其组成字符串返回secrets.token_hex(n)

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 给定一个正整数n 随机生成n个字节 即生成2n个十六进制数 将其组成字符串返回 secrets.token_hex(n) [太阳]选择题 根据题目代码&#xff0c;执行的结果错误的是&#xff1f; import secrets …

对vue响应式数据的理解(vue基础,面试,源码级讲解)

首先我们要知道哪些数据可以劫持。 是否可以劫持&#xff1a; 在JavaScript等动态语言中&#xff0c;字符串和数字虽然是基本数据类型&#xff08;也称为原始数据类型&#xff09;&#xff0c;但它们可以包装成对象&#xff08;如String对象和Number对象&#xff09;进行处理。…

软件测试笔记——接口测试

文章目录 一、概念1.接口测试流程2.URL3.HTTP协议4.RESTful5.案例介绍 二、Postman1.Postman软件2.登录接口调试-获取验证码3.登录接口调试-自动关联数据4.合同上传接口-提交请求数据5.提交参数查询6.批量执行7.接口用例设计8.断言8.参数化三、案例1.项目2.课程添加3.课程列表查…

萤石云服务支持云端视频AI自动剪辑生成

萤石视频云存储及媒体处理服务是围绕IoT设备云端存储场景下的音视频采集、媒体管理、视频剪辑和分发能力的一站式、专业云服务&#xff0c;并可面向广大开发者提供复杂设备存储场景下的完整技术方案。目前该服务新增了视频剪辑功能&#xff0c;支持将视频片段在云端进行裁剪并拼…