华为OD机试 - 求满足条件的最长子串的长度 - 滑动窗口(Python/JS/C/C++ 2025 A卷 100分)

在这里插入图片描述

华为OD机试 2025A卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

一、题目描述

给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度,字符串本身是其最长的子串,子串要求:

  1. 只包含1个字母(a-z, A-Z),其余必须是数字;
  2. 字母可以在子串中的任意位置;

如果找不到满足要求的子串,如全是字母或全是数字,则返回-1。

二、输入描述

字符串(只包含字母和数字)。

三、输出描述

子串的长度。

四、测试用例

输入输出说明
abC124ACb4满足条件的最长子串是C124或者124A,长度都是4
a52字符串本身就是满足要求的子串
aBB92满足条件的为B9,长度为2
abcdef-1没有满足条件的子串

五、解题思路

只包含1个字母(a-z, A-Z),其余必须是数字。

寻找这种字符串的最大长度。

关键点是只有一个字母。

再求此字母与其相连的数字,所能组成的最长子串。

六、Python算法源码

# 定义获取符合条件的最长子串的函数
def getResult(s):
    max_len = -1  # 初始化最大长度为-1
    has_letter = False  # 标记是否存在字母
    l = 0  # 左指针初始化为0
    r = 0  # 右指针初始化为0
    letter_idx = []  # 存储字母索引的列表

    while r < len(s):  # 当右指针小于字符串长度时循环
        c = s[r]  # 当前字符

        if c.isalpha():  # 如果字符是字母
            has_letter = True  # 标记有字母
            letter_idx.append(r)  # 将字母的索引加入列表

            # 如果字母数量超过一个,则更新左指针
            if len(letter_idx) > 1:
                l = letter_idx.pop(0) + 1  # 移除第一个字母索引,并更新左指针

            # 如果当前字符为字母且左指针和右指针相等,则跳过本轮
            if r == l:
                r += 1
                continue

        # 更新最大合法子串的长度
        max_len = max(max_len, r - l + 1)
        r += 1  # 移动右指针

    # 如果没有字母,则返回-1
    if not has_letter:
        return -1
    return max_len  # 返回最大合法子串的长度

七、JavaScript算法源码

// 定义获取符合条件的最长子串的函数
function getResult(str) {
    let maxLen = -1;  // 初始化最大长度为-1
    let hasLetter = false;  // 标记是否存在字母
    let l = 0;  // 左指针初始化为0
    let r = 0;  // 右指针初始化为0
    let letterIdx = [];  // 存储字母索引的数组

    // 遍历字符串
    while (r < str.length) {
        let c = str[r];  // 当前字符

        if (/[a-zA-Z]/.test(c)) {  // 如果字符是字母
            hasLetter = true;  // 标记有字母
            letterIdx.push(r);  // 将字母的索引加入数组

            // 如果字母数量超过一个,则更新左指针
            if (letterIdx.length > 1) {
                l = letterIdx.shift() + 1;  // 移除第一个字母索引,并更新左指针
            }

            // 如果当前字符为字母且左指针和右指针相等,则跳过本轮
            if (r === l) {
                r++;
                continue;
            }
        }

        // 更新最大合法子串的长度
        maxLen = Math.max(maxLen, r - l + 1);
        r++;  // 移动右指针
    }

    // 如果没有字母,则返回-1
    if (!hasLetter) return -1;
    return maxLen;  // 返回最大合法子串的长度
}

八、C算法源码

#include <stdio.h>
#include <string.h>
#include <ctype.h>

// 定义获取符合条件的最长子串的函数
int getResult(char *s) {
    int maxLen = -1;  // 初始化最大长度为-1
    int hasLetter = 0;  // 标记是否存在字母
    int l = 0;  // 左指针初始化为0
    int r = 0;  // 右指针初始化为0
    int letterIdx[1000];  // 存储字母索引的数组
    int letterCount = 0;  // 记录字母的数量

    // 遍历字符串
    while (r < strlen(s)) {
        char c = s[r];  // 当前字符

        if (isalpha(c)) {  // 如果字符是字母
            hasLetter = 1;  // 标记有字母
            letterIdx[letterCount++] = r;  // 将字母的索引加入数组

            // 如果字母数量超过一个,则更新左指针
            if (letterCount > 1) {
                l = letterIdx[0] + 1;  // 移除第一个字母索引,并更新左指针
                for (int i = 0; i < letterCount - 1; i++) {
                    letterIdx[i] = letterIdx[i + 1];  // 左移字母索引数组
                }
                letterCount--;
            }

            // 如果当前字符为字母且左指针和右指针相等,则跳过本轮
            if (r == l) {
                r++;
                continue;
            }
        }

        // 更新最大合法子串的长度
        maxLen = (maxLen > r - l + 1) ? maxLen : r - l + 1;
        r++;  // 移动右指针
    }

    // 如果没有字母,则返回-1
    if (!hasLetter) return -1;
    return maxLen;  // 返回最大合法子串的长度
}

九、C++算法源码

#include <iostream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;

// 定义获取符合条件的最长子串的函数
int getResult(string str) {
    int maxLen = -1;  // 初始化最大长度为-1
    bool hasLetter = false;  // 标记是否存在字母
    int l = 0;  // 左指针初始化为0
    int r = 0;  // 右指针初始化为0
    vector<int> letterIdx;  // 存储字母索引的向量

    // 遍历字符串
    while (r < str.length()) {
        char c = str[r];  // 当前字符

        if (isalpha(c)) {  // 如果字符是字母
            hasLetter = true;  // 标记有字母
            letterIdx.push_back(r);  // 将字母的索引加入向量

            // 如果字母数量超过一个,则更新左指针
            if (letterIdx.size() > 1) {
                l = letterIdx[0] + 1;  // 移除第一个字母索引,并更新左指针
                letterIdx.erase(letterIdx.begin());  // 删除向量的第一个元素
            }

            // 如果当前字符为字母且左指针和右指针相等,则跳过本轮
            if (r == l) {
                r++;
                continue;
            }
        }

        // 更新最大合法子串的长度
        maxLen = max(maxLen, r - l + 1);
        r++;  // 移动右指针
    }

    // 如果没有字母,则返回-1
    if (!hasLetter) return -1;
    return maxLen;  // 返回最大合法子串的长度
}

🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 A卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哪 吒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值