华为OD机试 2025A卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度,字符串本身是其最长的子串,子串要求:
- 只包含1个字母(a-z, A-Z),其余必须是数字;
- 字母可以在子串中的任意位置;
如果找不到满足要求的子串,如全是字母或全是数字,则返回-1。
二、输入描述
字符串(只包含字母和数字)。
三、输出描述
子串的长度。
四、测试用例
输入 | 输出 | 说明 |
---|---|---|
abC124ACb | 4 | 满足条件的最长子串是C124或者124A,长度都是4 |
a5 | 2 | 字符串本身就是满足要求的子串 |
aBB9 | 2 | 满足条件的为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算法的适用场景,发现新题目,随时更新。