华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
输入两个字符串S和L,都只包含小写字母,len(S) <= 100,len(L) <= 500000。判断S是否是L的有效子字符串。
判定规则:S中的每个字符在L中都能找到(可以不连续),且S在L中字符的前后顺序与S中顺序要保持一致。
例如:
S = "ace"是L = "abcde"的一个子序列,且有效字符是a、c、e,而"aec"不是有效子序列,且有效字符只有a、e(因为相对位置不同)。
二、输入描述
输入两个字符串S和L,都只包含小写字母,len(S) <= 100,len(L) <= 500000,先输入S再输入L 每个字符串占一行。
三、输出描述
S串**最后一个有效字符**在
L中的位置,首位从
0开始计算。无有效字符返回
-1
四、测试用例
1、输入
ace
abcde
2、输出
4
3、输入
fgh
abcde
4、输出
-1
五、解题思路
1、双指针法:
- 使用两个指针 i 和 j,分别遍历字符串 S 和 L。
- 初始化 i 和 j 均为0。
- 遍历 L,当 L[j] 等于 S[i] 时,移动 i 指针,否则移动 j 指针。
- 如果 i 移动到了 S 的末尾,则说明 S 是 L 的一个子序列,此时返回 j 的位置。
- 如果遍历完 L, i 还没有移动到 S 的末尾,则说明 S 不是 L 的一个子序列,返回 -1。
2、复杂度分析:
时间复杂度:O(n),其中 n 是字符串 L 的长度。每个字符最多被比较一次。
空间复杂度:O(1),只使用了常数级别的额外空间。
六、Python算法源码
def find_subsequence_end_position(S, L):
# 如果S为空,直接返回-1
if not S:
return -1
# 双指针初始化
i, j = 0, 0
len_s = len(S)
len_l = len(L)
# 遍历L,查找S的子序列
while j < len_l:
if L[j] == S[i]:
i += 1
# 如果i已经遍历完S,说明找到完整的子序列
if i == len_s:
return j # 返回最后一个匹配字符的位置
j += 1
# 如果遍历完L也没有找到完整的子序列,返回-1
return -1
def main():
S = input()
L = input()
print(find_subsequence_end_position(S, L))
if __name__ == "__main__":
main()
七、JavaScript算法源码
function findSubsequenceEndPosition(S, L) {
// 如果S为空,直接返回-1
if (S.length === 0) {
return -1;
}
// 双指针初始化
let i = 0, j = 0;
const lenS = S.length;
const lenL = L.length;
// 遍历L,查找S的子序列
while (j < lenL) {
if (L[j] === S[i]) {
i++;
// 如果i已经遍历完S,说明找到完整的子序列
if (i === lenS) {
return j; // 返回最后一个匹配字符的位置
}
}
j++;
}
// 如果遍历完L也没有找到完整的子序列,返回-1
return -1;
}
function main() {
const S = prompt("请输入字符串 S:");
const L = prompt("请输入字符串 L:");
const result = findSubsequenceEndPosition(S, L);
console.log(result);
}
// 调用主函数执行程序
main();
八、C算法源码
#include <stdio.h>
#include <string.h>
int findSubsequenceEndPosition(const char *S, const char *L) {
// 如果S为空,直接返回-1
if (S[0] == '\0') {
return -1;
}
// 双指针初始化
int i = 0, j = 0;
int lenS = strlen(S);
int lenL = strlen(L);
// 遍历L,查找S的子序列
while (j < lenL) {
if (L[j] == S[i]) {
i++;
// 如果i已经遍历完S,说明找到完整的子序列
if (i == lenS) {
return j; // 返回最后一个匹配字符的位置
}
}
j++;
}
// 如果遍历完L也没有找到完整的子序列,返回-1
return -1;
}
int main() {
char S[100], L[100];
// 读取输入的字符串S和L
printf("请输入字符串 S: ");
fgets(S, 100, stdin);
// 移除fgets读取时末尾可能包含的换行符
S[strcspn(S, "\n")] = '\0';
printf("请输入字符串 L: ");
fgets(L, 100, stdin);
// 移除fgets读取时末尾可能包含的换行符
L[strcspn(L, "\n")] = '\0';
int result = findSubsequenceEndPosition(S, L);
printf("%d\n", result);
return 0;
}
九、C++算法源码
#include <iostream>
#include <string>
int findSubsequenceEndPosition(const std::string &S, const std::string &L) {
// 如果S为空,直接返回-1
if (S.empty()) {
return -1;
}
// 双指针初始化
int i = 0, j = 0;
int lenS = S.length();
int lenL = L.length();
// 遍历L,查找S的子序列
while (j < lenL) {
if (L[j] == S[i]) {
i++;
// 如果i已经遍历完S,说明找到完整的子序列
if (i == lenS) {
return j; // 返回最后一个匹配字符的位置
}
}
j++;
}
// 如果遍历完L也没有找到完整的子序列,返回-1
return -1;
}
int main() {
std::string S, L;
// 读取输入的字符串S和L
std::cout << "请输入字符串 S: ";
std::getline(std::cin, S);
std::cout << "请输入字符串 L: ";
std::getline(std::cin, L);
int result = findSubsequenceEndPosition(S, L);
std::cout << result << std::endl;
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。