华为OD机试真题 - 有效子字符串 - 双指针(Python/JS/C/C++ 2024 D卷 100分)

在这里插入图片描述

华为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、双指针法:

  1. 使用两个指针 i 和 j,分别遍历字符串 S 和 L。
  2. 初始化 i 和 j 均为0。
  3. 遍历 L,当 L[j] 等于 S[i] 时,移动 i 指针,否则移动 j 指针。
  4. 如果 i 移动到了 S 的末尾,则说明 S 是 L 的一个子序列,此时返回 j 的位置。
  5. 如果遍历完 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在线答疑。

在这里插入图片描述

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值