一、问题描述
题目描述
小强正在参加《密室逃生》游戏,当前关卡要求找到符合给定密码K(升序的不重复小写字母组成)的箱子,并给出箱子编号,箱子编号为1~N。
每个箱子中都有一个字符串s,字符串由大写字母、小写字母、数字、标点符号、空格组成,需要在这些字符串中找到所有的字母,忽略大小写后排列出对应的密码串,并返回匹配密码的箱子序号。
提示:满足条件的箱子不超过1个。
输入描述
第一行为key的字符串,
第二行为箱子boxes,为数组样式,以空格分隔
箱子N数量满足1 ≤ N ≤ 10000,
s长度满足0 ≤ s.length ≤ 50,
密码为仅包含小写字母的升序字符串,且不存在重复字母,
密码K长度1 ≤ K.length ≤ 26
输出描述
返回对应箱子编号
如不存在符合要求的密码箱,则返回-1。
备注
箱子中字符拼出的字符串与密码的匹配忽略大小写,且要求与密码完全匹配,如密码abc匹配aBc,但是密码abc不匹配abcd
用例
输入
abc
s,sdf134 A2c4b
输出
2
说明
第2个箱子中的Abc,符合密码abc。
输入
abc
s,sdf134 A2c4bd 523[]
输出
-1
说明
第2个箱子中的Abcd,与密码不完全匹配,不符合要求
题目解析
2023.03.26 本题更新了题目描述,增加备注,增加了一个新用例。
问题分析
- 输入解析:题目描述中提到第二行输入的箱子字符串中可能包含空格,但输入描述又说让我们按照空格分割。这里默认第二行输入的每个箱子字符串中不包含空格。
- 匹配规则:题目要求箱子中的字符串与密码完全匹配,忽略大小写。这意味着:
- 箱子中的字符串必须包含密码中的所有字母,且顺序相同。
- 箱子中的字符串不能包含密码中没有的字母。
- 箱子中的字符串不能对字母进行去重处理。例如,箱子字符串
aabbcc
不能与密码abc
完全匹配。
解题思路
-
解析输入:
- 读取第一行的密码字符串
key
。 - 读取第二行的箱子字符串数组
boxes
,按空格分隔。
- 读取第一行的密码字符串
-
处理每个箱子:
- 对于每个箱子字符串,提取其中的所有字母,忽略大小写。
- 将提取的字母排序,形成一个新的字符串
box_str
。 - 比较
box_str
与key
是否完全匹配:- 如果匹配,返回该箱子的编号。
- 如果不匹配,继续处理下一个箱子。
-
返回结果:
- 如果所有箱子都不匹配,返回-1。
通过这种方法,我们可以有效地找到匹配密码的箱子编号。时间复杂度为O(n * m * log(m)),其中n是箱子的数量,m是箱子字符串的平均长度,log(m)是排序的时间复杂度。
二、JavaScript算法源码
以下是对您提供的 JavaScript 代码进行详细的中文注释和讲解,帮助更好地理解代码的功能和逻辑。
功能描述
这段代码的目标是:
给定一个升序、不重复的小写字母组成的密码 key
和一个字符串数组 boxes
,寻找 boxes
中第一个包含 key
所有字母(忽略大小写)的字符串。如果找到,返回该字符串在数组中的索引(1-based,即从 1 开始计数);否则返回 -1。
代码实现
1. 输入获取
javascript">const readline = require("readline");const rl = readline.createInterface({input: process.stdin, // 从标准输入读取数据output: process.stdout, // 输出到标准输出
});const lines = []; // 用于存储控制台输入的每一行
rl.on("line", (line) => {lines.push(line); // 每次用户输入一行时,把该行存储到 `lines` 中// 如果已经输入了两行,表示获取到了密码和字符串数组if (lines.length === 2) {const key = lines[0]; // 第一行是升序、不重复的小写字母组成的密码 keyconst boxes = lines[1].split(" "); // 第二行是字符串数组,按空格分割每个字符串console.log(getResult(key, boxes)); // 计算结果并输出到控制台lines.length = 0; // 清空 `lines` 数组,准备下一组输入}
});
输入获取逻辑
- 使用 Node.js 的
readline
模块管理控制台输入。 - 定义一个
lines
数组,用于保存每次输入的行数据。 - 当用户输入时,每一行通过
line
事件被捕获并存入lines
数组中。 - 当
lines
的长度到达 2 时:- 第一行
lines[0]
为密码key
。 - 第二行
lines[1]
为字符串数组,按空格拆分为boxes
。
- 第一行
- 调用
getResult
函数计算结果并输出。
2. 核心算法
javascript">/*** @param {*} key 升序的不重复小写字母组成的密码K* @param {*} boxes 数组,元素box为字符串* @returns 包含key的忽略大小写的所有字母的box*/
function getResult(key, boxes) {// 遍历字符串数组 `boxes`for (let i = 0; i < boxes.length; i++) {const box = boxes[i]; // 当前字符串const tmp = [...box.replace(/[^a-zA-Z]/g, "").toLowerCase()].sort().join("");// 如果当前字符串的处理结果与密码 `key` 匹配if (key == tmp) {return i + 1; // 返回当前字符串的位置(1-based 索引)}}return -1; // 如果没有匹配到,返回 -1
}
核心逻辑解析
1. 遍历字符串数组
javascript">for (let i = 0; i < boxes.length; i++) {const box = boxes[i]; // 获取数组中的每一个字符串
- 使用
for
循环逐一取出数组中的每个字符串box
。
2. 清理和标准化字符串
javascript">const tmp = [...box.replace(/[^a-zA-Z]/g, "").toLowerCase()].sort().join("");
这段代码对字符串 box
做了以下处理:
-
去除非字母字符:
javascript">box.replace(/[^a-zA-Z]/g, "")
- 使用正则表达式
/[^a-zA-Z]/g
清除box
中的所有非字母字符。[^a-zA-Z]
:匹配非字母的字符。g
:全局匹配,作用于整个字符串。
- 例子:
- 原始字符串:
"abc#123!"
-> 处理后:"abc"
。
- 原始字符串:
- 使用正则表达式
-
转换为小写:
javascript">.toLowerCase()
- 将字符串中所有字母转换为小写,忽略大小写匹配。
-
转为字符数组并排序:
javascript">[...string].sort()
- 使用扩展运算符
[...box]
将字符串拆分为字符数组。 - 使用
.sort()
对字符数组按字母顺序排序。 - 例子:
- 原始字符串:
"cba"
-> 字符数组:["c", "b", "a"]
-> 排序后:["a", "b", "c"]
。
- 原始字符串:
- 使用扩展运算符
-
重新拼接为字符串:
javascript">.join("")
- 使用
.join("")
将排序后的字符数组重新拼接为字符串。 - 例子:
- 排序后数组:
["a", "b", "c"]
-> 拼接后字符串:"abc"
。
- 排序后数组:
- 使用
3. 比较处理后的字符串与密码 key
javascript">if (key == tmp) {return i + 1; // 找到时返回 1-based 索引
}
- 如果当前字符串
box
的处理结果(tmp
)等于密码key
,则返回该字符串在数组中的索引(注意索引从 1 开始计数)。
4. 无匹配情况
javascript">return -1;
- 如果遍历结束都没有找到匹配的字符串,返回 -1 表示找不到。
3. 示例输入输出
输入示例 1
abc
aB#C Abc#123 Xyz
输出示例 1
2
解析:
- 输入的密码:
key = "abc"
- 输入的字符串数组:
boxes = ["aB#C", "Abc#123", "Xyz"]
- 算法处理:
- 第 1 个字符串
aB#C
:- 清理 + 转换为小写 + 排序:
"aB#C"
->"abc"
。 - 匹配成功。
- 清理 + 转换为小写 + 排序:
- 第 1 个字符串
- 返回该字符串的 1-based 索引
2
。
输入示例 2
xyz
Abc#123 Xyz
输出示例 2
-1
解析:
- 输入的密码:
key = "xyz"
- 输入的字符串数组:
boxes = ["Abc#123", "Xyz"]
- 算法处理:
- 第 1 个字符串
Abc#123
:- 清理 + 转换为小写 + 排序结果为:
"abc"
,不匹配。
- 清理 + 转换为小写 + 排序结果为:
- 第 2 个字符串
Xyz
:- 清理 + 转换为小写 + 排序结果为:
"xyz"
,不匹配。
- 清理 + 转换为小写 + 排序结果为:
- 第 1 个字符串
- 没有匹配到,返回 -1。
4. 总结
这段代码的核心逻辑是字符串的清理、标准化和比较,关键点包括:
- 使用正则表达式清除非字母字符。
- 忽略大小写,统一转小写。
- 使用排序确保字母顺序一致性。
- 遍历字符串数组,逐一检查是否满足条件,找到第一个匹配项。
适用场景:
- 判断字符串是否包含指定字符集。
- 处理忽略大小写和字符顺序的字符串比较问题。
如果还有其他疑问,请随时提问!
三、Java算法源码
以下是对您提供的 Java 代码的详细中文注释和讲解,帮助更好地理解代码的功能和逻辑。
功能描述
该程序的目标是:
给定一个由升序、不重复的小写字母组成的密码 key
和一个字符串数组 boxes
,寻找 boxes
中第一个包含 key
所有字符(忽略大小写)的字符串。如果找到,返回该字符串在数组中的索引(1-based,即从 1 开始计数);如果找不到,则返回 -1。
代码实现
1. 主程序入口
java">import java.util.Arrays;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String key = sc.nextLine(); // 从控制台读取密码 keyString[] boxes = sc.nextLine().split(" "); // 从控制台读取字符串数组,并按空格分割System.out.println(getResult(key, boxes)); // 调用函数计算结果并输出}
}
1.1. 输入逻辑
- 使用
Scanner
类从控制台读取输入。 - 调用
sc.nextLine()
读取第一行,作为密码key
。 - 调用
sc.nextLine()
读取第二行,并使用.split(" ")
方法按空格分隔成字符串数组boxes
。
2. 核心算法逻辑
java">public static int getResult(String key, String[] boxes) {for (int i = 0; i < boxes.length; i++) {String box = boxes[i]; // 获取字符串数组中的当前字符串char[] tmp = box.replaceAll("[^a-zA-Z]", "").toLowerCase().toCharArray();Arrays.sort(tmp);if (key.equals(new String(tmp))) {return i + 1; // 找到时返回 1-based 索引}}return -1; // 如果没有匹配到,返回 -1
}
2.1. 遍历字符串数组
java">for (int i = 0; i < boxes.length; i++) {String box = boxes[i]; // 获取数组中的每一个字符串
- 使用
for
循环逐一取出字符串数组boxes
中的每个字符串box
。
2.2. 清理和标准化字符串
java">char[] tmp = box.replaceAll("[^a-zA-Z]", "").toLowerCase().toCharArray();
这段代码对字符串 box
做了以下处理:
-
去除非字母字符:
java">box.replaceAll("[^a-zA-Z]", "")
- 使用正则表达式
[^a-zA-Z]
匹配非字母字符。 - 通过
replaceAll
方法将这些字符替换为空字符串。 - 例子:
- 原始字符串:
"abc#123!"
-> 处理后:"abc"
。
- 原始字符串:
- 使用正则表达式
-
转换为小写:
java">.toLowerCase()
- 将字符串中所有字母转换为小写,忽略大小写匹配。
- 例子:
- 原始字符串:
"AbC"
-> 转换后:"abc"
。
- 原始字符串:
-
转为字符数组:
java">.toCharArray()
- 将字符串拆分为字符数组,以便后续进行排序。
- 例子:
- 字符串:
"abc"
-> 字符数组:['a', 'b', 'c']
。
- 字符串:
2.3. 排序字符数组
java">Arrays.sort(tmp);
- 使用
Arrays.sort()
将字符数组按照字母顺序排序。 - 排序的目的是确保字符的顺序与密码
key
一致,以便进行比较。 - 例子:
- 原始字符数组:
['c', 'b', 'a']
-> 排序后:['a', 'b', 'c']
。
- 原始字符数组:
2.4. 比较处理后的字符串与密码 key
java">if (key.equals(new String(tmp))) {return i + 1; // 找到时返回 1-based 索引
}
- 将排序后的字符数组转换为字符串(通过
new String(tmp)
),并与密码key
进行比较。 - 如果相等,说明当前
box
的字符完全匹配密码key
。 - 返回当前字符串的位置索引(1-based,即从 1 开始计数)。
2.5. 无匹配情况
java">return -1;
- 如果遍历完所有字符串后都没有找到匹配项,则返回 -1,表示找不到符合条件的字符串。
3. 示例输入输出
输入示例 1
abc
aB#C Abc#123 Xyz
输出示例 1
2
解析:
- 输入的密码:
key = "abc"
- 输入的字符串数组:
boxes = ["aB#C", "Abc#123", "Xyz"]
- 算法处理:
- 第 1 个字符串
aB#C
:- 清理 + 转换为小写 + 排序:
"aB#C"
->"abc"
。 - 匹配成功。
- 清理 + 转换为小写 + 排序:
- 返回第 1 个字符串的 1-based 索引
2
。
- 第 1 个字符串
输入示例 2
xyz
Abc Xyz#789
输出示例 2
2
解析:
- 输入的密码:
key = "xyz"
- 输入的字符串数组:
boxes = ["Abc", "Xyz#789"]
- 算法处理:
- 第 1 个字符串
Abc
:- 清理 + 转换为小写 + 排序:
"Abc"
->"abc"
。 - 不匹配。
- 清理 + 转换为小写 + 排序:
- 第 2 个字符串
Xyz#789
:- 清理 + 转换为小写 + 排序:
"Xyz#789"
->"xyz"
。 - 匹配成功。
- 清理 + 转换为小写 + 排序:
- 返回第 2 个字符串的 1-based 索引
2
。
- 第 1 个字符串
输入示例 3
abc
Xyz Def
输出示例 3
-1
解析:
- 输入的密码:
key = "abc"
- 输入的字符串数组:
boxes = ["Xyz", "Def"]
- 算法处理:
- 所有字符串中都未能匹配密码
key
。 - 返回 -1。
- 所有字符串中都未能匹配密码
4. 总结
这段 Java 代码的功能清晰,实现了一个简单且高效的算法,关键点包括:
- 清理字符串:通过正则表达式去掉非字母字符。
- 标准化字符串:忽略大小写,并排序字符。
- 逐一匹配:逐一检查字符串数组中的字符是否与密码
key
匹配。
适用场景:
- 用于解决字符串字符集匹配问题。
- 常用于忽略大小写和字符顺序的字符串比较场景。
如果还有其他疑问,欢迎随时提问!
四、Python算法源码
以下是对您提供的 Python 代码的详细中文注释和讲解,帮助您深入理解代码的功能和运行逻辑。
功能描述
该程序旨在解决如下问题:
给定一个升序、不重复的小写字母组成的密码 key
和一个字符串数组 boxes
,在 boxes
中寻找第一个包含 key
所有字母(忽略大小写)的字符串。如果找到,返回该字符串在数组中的索引(从 1 开始计数);如果找不到,返回 -1。
代码实现
1. 输入获取
python">key = input()
boxes = input().split()
代码解析:
-
读取密码
key
:- 使用
input()
方法从控制台读取用户输入的一行字符串,作为密码key
。 - 例子:
- 用户输入:
abc
存储:key = "abc"
。
- 用户输入:
- 使用
-
读取字符串数组
boxes
:- 使用
input()
方法从控制台读取用户输入的另一行,并用.split()
方法按空格分割成字符串列表。 - 例子:
- 用户输入:
aB#C Abc#123 Xyz
存储:boxes = ["aB#C", "Abc#123", "Xyz"]
。
- 用户输入:
- 使用
2. 核心算法入口
python">def getResult(key, boxes):
代码解析:
- 定义一个函数
getResult
,该函数接收两个参数:key
:密码,目标是与字符串匹配。boxes
:字符串列表,目标是找到第一个包含key
所有字母的字符串。
3. 遍历字符串数组
python">for i in range(len(boxes)):box = boxes[i]
代码解析:
-
遍历字符串数组:
- 使用
for
循环按索引(i
)逐一获取boxes
中的每个字符串box
。
- 使用
-
访问当前字符串:
boxes[i]
表示当前索引i
处的字符串。
4. 清理和标准化字符串
python">tmp = list("".join(list(filter(lambda c: 'a' <= c <= 'z' or 'A' <= c <= 'Z', list(box)))).lower())
代码解析:
对当前字符串 box
进行处理,提取出字母并标准化:
-
拆分为字符列表:
python">list(box)
- 将字符串
box
转换为字符列表,便于逐个字符筛选。 - 例子:
box = "aB#C123"
->['a', 'B', '#', 'C', '1', '2', '3']
。
- 将字符串
-
过滤出字母字符:
python">filter(lambda c: 'a' <= c <= 'z' or 'A' <= c <= 'Z', list(box))
- 使用
filter
函数过滤字符,仅保留字母(包括大小写)。 lambda c: 'a' <= c <= 'z' or 'A' <= c <= 'Z'
是一个匿名函数,用于判断字符是否为字母。- 例子:
- 输入字符列表:
['a', 'B', '#', 'C', '1', '2', '3']
-> 过滤后:['a', 'B', 'C']
。
- 输入字符列表:
- 使用
-
将字符拼接为字符串:
python">"".join(filtered_characters)
- 使用
"".join(...)
将过滤后的字符列表拼接为字符串。 - 例子:
- 字符列表:
['a', 'B', 'C']
-> 拼接后:"aBC"
。
- 字符列表:
- 使用
-
转换为小写:
python">.lower()
- 将整个字符串转换为小写,以忽略大小写的影响。
- 例子:
"aBC"
->"abc"
。
-
转换为字符列表:
python">list(...)
- 进一步将字符串转换为字符列表,以便排序。
- 例子:
"abc"
->['a', 'b', 'c']
。
5. 排序字符数组
python">tmp.sort()
代码解析:
- 使用
.sort()
对字符列表tmp
按升序排序,以确保字符顺序与密码key
一致。 - 例子:
- 原始字符数组:
['c', 'b', 'a']
-> 排序后:['a', 'b', 'c']
。
- 原始字符数组:
6. 比较处理后的字符串与密码
python">if key == "".join(tmp):return i + 1
代码解析:
-
将字符列表拼接为字符串:
python">"".join(tmp)
- 将排序后的字符列表
tmp
转换回字符串,用于与密码key
进行比较。 - 例子:
- 排序后的字符列表:
['a', 'b', 'c']
-> 字符串:"abc"
。
- 排序后的字符列表:
- 将排序后的字符列表
-
比较是否匹配:
python">if key == ...
- 如果当前字符串的处理结果等于密码
key
,说明它包含了密码的所有字符(并且无多余字符)。
- 如果当前字符串的处理结果等于密码
-
返回 1-based 索引:
python">return i + 1
- 返回当前字符串的索引(从 1 开始计数)。
7. 无匹配情况
python">return -1
代码解析:
- 如果遍历结束后仍未找到符合条件的字符串,返回 -1,表示找不到匹配项。
8. 算法调用
python">print(getResult(key, boxes))
代码解析:
- 调用
getResult
函数,传入输入的key
和boxes
。 - 将返回值通过
print
输出到控制台。
示例输入输出
输入示例 1
abc
aB#C Abc#123 Xyz
输出示例 1
1
解析:
- 输入密码:
key = "abc"
- 输入字符串数组:
boxes = ["aB#C", "Abc#123", "Xyz"]
- 算法处理:
- 第 1 个字符串
aB#C
:- 清理:
"aB#C"
->"abc"
。 - 排序:
"abc"
->"abc"
。 - 匹配成功。
- 清理:
- 返回索引:1。
- 第 1 个字符串
输入示例 2
xyz
Abc#123 Xyz
输出示例 2
2
解析:
- 第 2 个字符串
Xyz
:- 清理 + 标准化 ->
"xyz"
。 - 匹配成功,返回索引 2。
- 清理 + 标准化 ->
输入示例 3
abc
Xyz Def
输出示例 3
-1
解析:
- 没有任何字符串匹配
key = "abc"
。 - 返回 -1。
总结
重点处理了字符串的清理、标准化以及匹配,适用于字符集匹配问题。其核心点在于:
- 过滤非字母字符:通过
filter
去除无关字符。 - 忽略大小写:通过
.lower()
转换为小写。 - 字符排序:通过
sort()
保证字符顺序一致。 - 逐一匹配:逐个检查字符串是否符合条件。
如果还有其他疑问,欢迎随时提问!
五、C/C++算法源码:
以下是C++ 和 C 代码版本,并附上详细的中文注释和讲解。
C++ 代码实现
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;int getResult(string key, vector<string>& boxes);int main() {string key;getline(cin, key); // 从控制台读取密码 keystring input;getline(cin, input); // 从控制台读取字符串数组 inputvector<string> boxes;string temp;for (char c : input) {if (c == ' ') {if (!temp.empty()) {boxes.push_back(temp); // 按空格分隔字符串,存入 boxestemp.clear();}} else {temp += c;}}if (!temp.empty()) {boxes.push_back(temp); // 最后一个字符串加入 boxes}cout << getResult(key, boxes) << endl; // 调用函数并输出结果return 0;
}int getResult(string key, vector<string>& boxes) {for (int i = 0; i < boxes.size(); i++) {string box = boxes[i];// 1. 删除非字母字符并转换为小写string filtered;for (char c : box) {if (isalpha(c)) { // 判断是否为字母filtered += tolower(c); // 转换为小写并加入新字符串}}// 2. 对字符串排序sort(filtered.begin(), filtered.end());// 3. 判断排序后的字符串是否等于 keyif (filtered == key) {return i + 1; // 找到匹配的字符串,返回 1-based 索引}}return -1; // 没有匹配的字符串
}
C++ 代码详解
-
读取输入:
- 使用
getline(cin, key)
获取第一行的密码key
。 - 使用
getline(cin, input)
获取第二行的字符串数组input
。
- 使用
-
分割字符串:
- 遍历
input
,按空格分隔成多个子字符串,并存入boxes
向量。
- 遍历
-
逐个处理:
- 遍历
boxes
,逐一处理每个字符串。 - 使用
isalpha(c)
判断字符是否为字母,忽略非字母字符。 - 使用
tolower(c)
将字母转换为小写。
- 遍历
-
排序和比较:
- 使用
sort()
对字符串排序。 - 判断排序后的字符串是否与
key
相等。
- 使用
-
返回结果:
- 如果找到匹配的字符串,返回其索引(1-based)。
- 如果找不到,返回 -1。
C 代码实现
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>// 函数声明
int getResult(const char* key, char boxes[][101], int n);int main() {char key[101];fgets(key, 101, stdin); // 从控制台读取密码 keykey[strcspn(key, "\n")] = '\0'; // 去掉换行符char input[1001];fgets(input, 1001, stdin); // 从控制台读取字符串数组 inputinput[strcspn(input, "\n")] = '\0'; // 去掉换行符char boxes[100][101]; // 假设最多有 100 个字符串,每个字符串最长 100 个字符int count = 0;char* token = strtok(input, " "); // 按空格分割while (token != NULL) {strcpy(boxes[count++], token);token = strtok(NULL, " ");}printf("%d\n", getResult(key, boxes, count)); // 调用函数并输出结果return 0;
}int getResult(const char* key, char boxes[][101], int n) {for (int i = 0; i < n; i++) {char* box = boxes[i];char filtered[101] = {0}; // 存储过滤后的字符串int index = 0;// 1. 删除非字母字符并转换为小写for (int j = 0; box[j] != '\0'; j++) {if (isalpha(box[j])) { // 判断是否为字母filtered[index++] = tolower(box[j]); // 转换为小写并添加到 filtered}}filtered[index] = '\0'; // 添加字符串结束符// 2. 对字符串排序int len = strlen(filtered);qsort(filtered, len, sizeof(char), (int (*)(const void*, const void*)) strcmp);// 3. 判断排序后的字符串是否等于 keyif (strcmp(key, filtered) == 0) {return i + 1; // 找到匹配的字符串,返回 1-based 索引}}return -1; // 没有匹配的字符串
}
C 代码详解
-
输入处理:
- 使用
fgets
读取密码key
和字符串数组input
。 - 使用
strtok
按空格将字符串分割成多个子字符串,存入boxes
二维数组。
- 使用
-
逐个处理字符串:
- 遍历
boxes
中的每个字符串。 - 使用
isalpha
判断字符是否为字母。 - 使用
tolower
将字母转换为小写,并存入filtered
字符数组。
- 遍历
-
排序和比较:
- 使用
qsort
对filtered
字符串排序。 - 使用
strcmp
比较排序后的字符串和key
是否相等。
- 使用
-
返回结果:
- 如果找到符合条件的字符串,返回其索引(1-based)。
- 如果找不到,返回 -1。
示例输入输出
输入示例
abc
aB#C Abc#123 Xyz
输出示例
1
输入解析
- 密码
key
="abc"
。 - 字符串数组
boxes
=["aB#C", "Abc#123", "Xyz"]
。
处理步骤
-
处理第一个字符串:
- 原始字符串:
"aB#C"
。 - 过滤并转换为小写:
"abc"
。 - 排序后:
"abc"
。 - 匹配成功,返回索引 1。
- 原始字符串:
-
结果输出:
- 输出
1
。
- 输出
总结
- C++ 和 C 的实现均遵循与 Java 代码相同的逻辑。
- C++ 的 STL 功能(如
std::sort
和std::string
)使代码更简洁。 - C 语言需要更多的手动处理(如字符串操作和内存管理),但逻辑完全相同。
如有其他问题,欢迎继续提问!
六、尾言
什么是华为OD?
华为OD(Outsourcing Developer,外包开发工程师)是华为针对软件开发工程师岗位的一种招聘形式,主要包括笔试、技术面试以及综合面试等环节。尤其在笔试部分,算法题的机试至关重要。
为什么刷题很重要?
-
机试是进入技术面的第一关:
华为OD机试(常被称为机考)主要考察算法和编程能力。只有通过机试,才能进入后续的技术面试环节。 -
技术面试需要手撕代码:
技术一面和二面通常会涉及现场编写代码或算法题。面试官会注重考察候选人的思路清晰度、代码规范性以及解决问题的能力。因此提前刷题、多练习是通过面试的重要保障。 -
入职后的可信考试:
入职华为后,还需要通过“可信考试”。可信考试分为三个等级:- 入门级:主要考察基础算法与编程能力。
- 工作级:更贴近实际业务需求,可能涉及复杂的算法或与工作内容相关的场景题目。
- 专业级:最高等级,考察深层次的算法以及优化能力,与薪资直接挂钩。
刷题策略与说明:
2024年8月14日之后,华为OD机试的题库转为 E卷,由往年题库(D卷、A卷、B卷、C卷)和全新题目组成。刷题时可以参考以下策略:
-
关注历年真题:
- 题库中的旧题占比较大,建议优先刷历年的A卷、B卷、C卷、D卷题目。
- 对于每道题目,建议深度理解其解题思路、代码实现,以及相关算法的适用场景。
-
适应新题目:
- E卷中包含全新题目,需要掌握全面的算法知识和一定的灵活应对能力。
- 建议关注新的刷题平台或交流群,获取最新题目的解析和动态。
-
掌握常见算法:
华为OD考试通常涉及以下算法和数据结构:- 排序算法(快速排序、归并排序等)
- 动态规划(背包问题、最长公共子序列等)
- 贪心算法
- 栈、队列、链表的操作
- 图论(最短路径、最小生成树等)
- 滑动窗口、双指针算法
-
保持编程规范:
- 注重代码的可读性和注释的清晰度。
- 熟练使用常见编程语言,如C++、Java、Python等。
如何获取资源?
-
官方参考:
- 华为招聘官网或相关的招聘平台会有一些参考信息。
- 华为OD的相关公众号可能也会发布相关的刷题资料或学习资源。
-
加入刷题社区:
- 找到可信的刷题交流群,与其他备考的小伙伴交流经验。
- 关注知名的刷题网站,如LeetCode、牛客网等,这些平台上有许多华为OD的历年真题和解析。
-
寻找系统性的教程:
- 学习一本经典的算法书籍,例如《算法导论》《剑指Offer》《编程之美》等。
- 完成系统的学习课程,例如数据结构与算法的在线课程。
积极心态与持续努力:
刷题的过程可能会比较枯燥,但它能够显著提升编程能力和算法思维。无论是为了通过华为OD的招聘考试,还是为了未来的职业发展,这些积累都会成为重要的财富。
考试注意细节
-
本地编写代码
- 在本地 IDE(如 VS Code、PyCharm 等)上编写、保存和调试代码,确保逻辑正确后再复制粘贴到考试页面。这样可以减少语法错误,提高代码准确性。
-
调整心态,保持冷静
- 遇到提示不足或实现不确定的问题时,不必慌张,可以采用更简单或更有把握的方法替代,确保思路清晰。
-
输入输出完整性
- 注意训练和考试时都需要编写完整的输入输出代码,尤其是和题目示例保持一致。完成代码后务必及时调试,确保功能符合要求。
-
快捷键使用
- 删除行可用
Ctrl+D
,复制、粘贴和撤销分别为Ctrl+C
,Ctrl+V
,Ctrl+Z
,这些可以正常使用。 - 避免使用
Ctrl+S
,以免触发浏览器的保存功能。
- 删除行可用
-
浏览器要求
- 使用最新版的 Google Chrome 浏览器完成考试,确保摄像头开启并正常工作。考试期间不要切换到其他网站,以免影响考试成绩。
-
交卷相关
- 答题前,务必仔细查看题目示例,避免遗漏要求。
- 每完成一道题后,点击【保存并调试】按钮,多次保存和调试是允许的,系统会记录得分最高的一次结果。完成所有题目后,点击【提交本题型】按钮。
- 确保在考试结束前提交试卷,避免因未保存或调试失误而丢分。
-
时间和分数安排
- 总时间:150 分钟;总分:400 分。
- 试卷结构:2 道一星难度题(每题 100 分),1 道二星难度题(200 分)。及格分为 150 分。合理分配时间,优先完成自己擅长的题目。
-
考试环境准备
- 考试前请备好草稿纸和笔。考试中尽量避免离开座位,确保监控画面正常。
- 如需上厕所,请提前规划好时间以减少中途离开监控的可能性。
-
技术问题处理
- 如果考试中遇到断电、断网、死机等技术问题,可以关闭浏览器并重新打开试卷链接继续作答。
- 出现其他问题,请第一时间联系 HR 或监考人员进行反馈。
祝你考试顺利,取得理想成绩!