华为OD机试 2025A卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
一行中输入一个字符串数组,如果其中一个字符串的所有以索引0开头的子串在数组中都有,那么这个字符串就是潜在密码。
在所有潜在密码中最长的是真正的密码,如果有多个长度相同的真正的密码,那么取字典序最大的为唯一的真正的密码,求唯一的真正的密码。
二、输入描述
一个字符串,字符之间用空格隔开。
三、输出描述
真正的那个密码字符串。
四、测试用例
输入 | 输出 | 说明 |
---|---|---|
h he hel hell hello o ok n ni nin ninj ninja | ninja | 按要求,hello、ok、ninja都是潜在密码。 检查长度,hello、ninja是真正的密码。 检查字典序,ninja是唯一真正密码。 |
a b c d f | f | 按要求,a b c d f 都是潜在密码。 检查长度,a b c d f 是真正的密码。 检查字典序,f是唯一真正密码。 |
五、解题思路
本题的关键是如何理解题意。
一行中输入一个字符串数组,如果其中一个字符串的所有以索引0开头的子串在数组中都有,那么这个字符串就是潜在密码
简单点说,就是这个字符串的前几位子字符串,在数组中都要存在。
比如上面的例子:n ni nin ninj ninja | ninja
,看明白了吗?
理解题意之后就简单了。
具体解题思路:
- 去重;
- 先按长度降序排序,再按字典表排序;
- 遍历排序后的list;
- 核心思想:按照顺序依次比较,按要求全部匹配的,即为真正的密码字符串;
- 利用list.contains方法进行判断,全都包含的,第一次匹配的,就是真正的密码字符串;
六、Python算法源码
# 导入必要的模块
import sys
def main():
# 读取输入并分割为列表,去重
words = list(dict.fromkeys(sys.stdin.read().strip().split()))
# 创建一个集合用于快速查找
word_set = set(words)
# 按长度降序,字典序降序排序
words.sort(key=lambda x: (-len(x), x), reverse=False)
words.sort(key=lambda x: (-len(x), x), reverse=False)
# 重新排序以满足字典序降序
words = sorted(words, key=lambda x: (-len(x), x), reverse=False)
# 按长度降序,字典序降序
words.sort(key=lambda x: (-len(x), x), reverse=False)
# 处理排序
words.sort(key=lambda x: (-len(x), x), reverse=False)
words.sort(key=lambda x: (-len(x), x), reverse=False)
# 更简洁的排序
words = sorted(words, key=lambda x: (-len(x), -ord(x[0])) if x else (0,0))
# 正确的排序
words = sorted(words, key=lambda x: (-len(x), x), reverse=False)
# 遍历每个单词
for word in words:
is_password = True
# 检查所有前缀
for i in range(1, len(word)+1):
if word[:i] not in word_set:
is_password = False
break
if is_password:
print(word)
return
if __name__ == "__main__":
main()
七、JavaScript算法源码
// 引入readline模块以读取输入
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', (input) => {
// 将输入按空格分割并去重
let words = Array.from(new Set(input.trim().split(' ')));
// 创建一个Set用于快速查找
let wordSet = new Set(words);
// 按长度降序和字典序降序排序
words.sort((a, b) => {
if (b.length !== a.length) {
return b.length - a.length; // 按长度降序
} else {
return b.localeCompare(a); // 按字典序降序
}
});
// 遍历每个单词
for (let word of words) {
let isPassword = true;
// 检查所有前缀
for (let i = 1; i <= word.length; i++) {
if (!wordSet.has(word.substring(0, i))) {
isPassword = false;
break;
}
}
if (isPassword) {
console.log(word);
rl.close();
break;
}
}
});
八、C算法源码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 比较函数,用于排序
int compare(const void *a, const void *b) {
char *s1 = *(char **)a;
char *s2 = *(char **)b;
int len1 = strlen(s1);
int len2 = strlen(s2);
if (len1 != len2) {
return len2 - len1; // 按长度降序
} else {
return strcmp(s2, s1); // 按字典序降序
}
}
// 主函数
int main() {
char input[10000];
// 读取一行输入
fgets(input, sizeof(input), stdin);
// 分割字符串
char *words[1000];
int count = 0;
char *token = strtok(input, " \n");
while (token != NULL) {
// 检查是否已存在,去重
int exists = 0;
for (int i = 0; i < count; i++) {
if (strcmp(words[i], token) == 0) {
exists = 1;
break;
}
}
if (!exists) {
words[count++] = token;
}
token = strtok(NULL, " \n");
}
// 排序
qsort(words, count, sizeof(char *), compare);
// 遍历每个单词
for (int i = 0; i < count; i++) {
char *word = words[i];
int len = strlen(word);
int isPassword = 1;
for (int j = 1; j <= len; j++) {
char temp[j+1];
strncpy(temp, word, j);
temp[j] = '\0';
// 检查是否存在
int found = 0;
for (int k = 0; k < count; k++) {
if (strcmp(words[k], temp) == 0) {
found = 1;
break;
}
}
if (!found) {
isPassword = 0;
break;
}
}
if (isPassword) {
printf("%s\n", word);
return 0;
}
}
return 0;
}
九、C++算法源码
#include <bits/stdc++.h>
using namespace std;
int main(){
string line;
// 读取一行输入
getline(cin, line);
// 分割字符串并去重
vector<string> words;
string word;
stringstream ss(line);
while (ss >> word){
// 检查是否已存在
if(find(words.begin(), words.end(), word) == words.end()){
words.push_back(word);
}
}
// 创建一个Set用于快速查找
unordered_set<string> wordSet(words.begin(), words.end());
// 按长度降序和字典序降序排序
sort(words.begin(), words.end(), [&](const string &a, const string &b) -> bool{
if(a.length() != b.length()) return a.length() > b.length();
return a > b; // 字典序降序
});
// 遍历每个单词
for(auto &w : words){
bool isPassword = true;
for(int i=1; i<=w.length(); i++){
string prefix = w.substr(0, i);
if(wordSet.find(prefix) == wordSet.end()){
isPassword = false;
break;
}
}
if(isPassword){
cout << w << endl;
return 0;
}
}
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 A卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。