2025华为OD机试题库(按算法分类):2025华为OD统一考试题库清单(持续收录中)以及考点说明(Python/JS/C/C++)。
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
电视剧《分界线》里面有一个片段,男主为了向警察透露案件细节,且不暴露自己,于是将报刊上的字剪切下来,剪拼成匿名信。现在有一名举报人,希望借鉴这种手段,使用英文报刊完成举报操作。
但为了增加文章的混淆度,只需满足每个单词中字母数量一致即可,不关注每个字母的顺序解释:单词on允许通过单词’no’进行替代报纸代表newspaper,匿名信代表anonymousLetter,求报纸内容是否可以拼成匿名信。
二、输入描述
第一行输入newspaper内容,包括1-N个字符串,用空格分开
第二行输入anonymousLetter内容,包括1-N个字符串,用空格分开
- newspaper和anonymousLetter的字符串由小写英文字母组成且每个字母只能使用一次;
- newspaper内容中的每个字符串字母顺序可以任意调整,但必须保证字符串的完整性(每个字符串不能有多余字母);
- 1<N<100 , 1<= newspaper.length, anonymousLetter.length <= 104;
三、输出描述
如果报纸可以拼成匿名信返回ture,否则返回false。
四、测试用例
1、输入
ac df
adf
2、输出
false
五、解题思路
- 读取输入的报纸内容和匿名信内容。
- 将报纸内容和匿名信内容分别以空格为分隔符拆分成字符串数组。
- 创建一个HashSet,用于存储报纸内容中每个字符串按字母排序后的值。
- 遍历报纸内容数组:
- 对于每个字符串,将其转换为字符数组,并按字母顺序进行排序。
- 将排序后的字符数组转换为字符串,并添加到HashSet中。
- 创建一个布尔变量flag,并将其初始化为true。
- 遍历匿名信内容数组:
- 对于每个字符串,将其转换为字符数组,并按字母顺序进行排序。
- 将排序后的字符数组转换为字符串。
- 如果HashSet中不包含该字符串,则将flag设为false,并跳出循环。
- 根据flag的值,输出"true"或"false"表示报纸是否可以拼成匿名信。
该算法的时间复杂度为O(N+M)
,其中N是报纸内容的长度,M是匿名信内容的长度。因为需要遍历两个字符串数组,对每个字符串进行排序,并将排序后的字符串存储到HashSet中。最终的空间复杂度为O(N)
,取决于HashSet的存储空间。
六、Python算法源码
# -*- coding: utf-8 -*-
def canFormAnonymousLetter():
# 读取报纸内容和匿名信内容,并去除两端空白字符
newspaper = input().strip()
anonymous = input().strip()
# 按空格分割成单词列表
words_newspaper = newspaper.split()
words_anonymous = anonymous.split()
# 使用字典统计报纸中每个单词(字母排序后)的频率
freq = {}
for word in words_newspaper:
sorted_word = ''.join(sorted(word)) # 对单词中的字母排序
freq[sorted_word] = freq.get(sorted_word, 0) + 1 # 统计该排序后单词的数量
# 遍历匿名信中的每个单词,检查是否能在报纸中匹配
for word in words_anonymous:
sorted_word = ''.join(sorted(word))
if sorted_word not in freq or freq[sorted_word] == 0:
# 若没有对应单词或数量不足,则返回False
return False
else:
freq[sorted_word] -= 1 # 使用该单词后,数量减1
return True
# 调用函数并打印结果,转换为小写字符串形式
print(str(canFormAnonymousLetter()).lower())
七、JavaScript算法源码
function canFormAnonymousLetter() {
// 引入fs模块用于读取标准输入
const fs = require('fs');
// 读取全部输入数据并按换行符分割
let input = fs.readFileSync(0, 'utf-8').trim().split('\n');
let newspaper = input[0].trim(); // 第一行:报纸内容
let anonymous = input[1].trim(); // 第二行:匿名信内容
// 按空格分割字符串为单词数组
let wordsNewspaper = newspaper.split(/\s+/);
let wordsAnonymous = anonymous.split(/\s+/);
// 使用对象(字典)统计报纸中每个单词(字母排序后)的出现次数
let freq = {};
for (let word of wordsNewspaper) {
// 将单词拆分成字符数组、排序、再合并为字符串
let sortedWord = word.split('').sort().join('');
freq[sortedWord] = (freq[sortedWord] || 0) + 1; // 更新频率
}
// 遍历匿名信单词,检查每个单词是否有足够的匹配
for (let word of wordsAnonymous) {
let sortedWord = word.split('').sort().join('');
if (!freq[sortedWord] || freq[sortedWord] <= 0) {
// 若对应单词不存在或数量不足,则返回false
return false;
}
freq[sortedWord]--; // 使用后数量减1
}
return true;
}
// 调用函数并输出结果
console.log(String(canFormAnonymousLetter()));
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// 定义最大行长度(根据题目输入范围可适当调整)
#define MAX_LINE_LEN 100000
// 定义最大单词数(题目要求 <= 10^4)
#define MAX_WORDS 10000
// 定义结构体保存单词及其出现次数
typedef struct {
char *word; // 存储排序后的单词
int count; // 该单词出现的次数
} WordCount;
// 辅助函数:比较两个字符(用于qsort)
int cmpChar(const void *a, const void *b) {
return (*(char*)a - *(char*)b);
}
// 辅助函数:对字符串中的字母排序,返回排序后的新字符串(需free)
char* sortString(const char *s) {
int len = strlen(s);
char *temp = (char*)malloc(len + 1);
strcpy(temp, s);
qsort(temp, len, sizeof(char), cmpChar);
return temp; // 调用者负责释放内存
}
// 主函数
int main(){
char line1[MAX_LINE_LEN], line2[MAX_LINE_LEN];
// 读取两行输入
if(fgets(line1, sizeof(line1), stdin) == NULL) return 1;
if(fgets(line2, sizeof(line2), stdin) == NULL) return 1;
// 去除末尾可能的换行符
line1[strcspn(line1, "\n")] = '\0';
line2[strcspn(line2, "\n")] = '\0';
WordCount freq[MAX_WORDS]; // 存储频率的数组
int freqSize = 0; // 当前不同单词的数量
// 使用 strtok 分割报纸行(第一行)
char *token = strtok(line1, " ");
while(token != NULL) {
// 对单词进行排序
char *sortedWord = sortString(token);
// 在freq数组中查找是否已存在该单词
int found = 0;
for (int i = 0; i < freqSize; i++) {
if(strcmp(freq[i].word, sortedWord) == 0) {
freq[i].count++;
found = 1;
break;
}
}
if(!found) {
// 若未找到,则添加新的记录
freq[freqSize].word = sortedWord; // 注意:sortedWord已经分配内存
freq[freqSize].count = 1;
freqSize++;
} else {
free(sortedWord); // 已存在,则释放刚分配的内存
}
token = strtok(NULL, " ");
}
int flag = 1; // 标记是否可以拼出匿名信
// 处理匿名信行(第二行)
token = strtok(line2, " ");
while(token != NULL) {
char *sortedWord = sortString(token);
int found = 0;
for (int i = 0; i < freqSize; i++) {
if(strcmp(freq[i].word, sortedWord) == 0 && freq[i].count > 0) {
// 找到对应单词且数量足够,扣减数量
freq[i].count--;
found = 1;
break;
}
}
if(!found) {
flag = 0; // 无法匹配
free(sortedWord);
break;
}
free(sortedWord);
token = strtok(NULL, " ");
}
// 输出结果
if(flag)
printf("true\n");
else
printf("false\n");
// 释放freq数组中分配的内存
for (int i = 0; i < freqSize; i++) {
free(freq[i].word);
}
return 0;
}
九、C++算法源码
#include <iostream>
#include <sstream>
#include <unordered_map>
#include <algorithm>
#include <string>
using namespace std;
int main(){
// 读取整行输入
string line1, line2;
getline(cin, line1); // 第一行:报纸内容
getline(cin, line2); // 第二行:匿名信内容
// 使用istringstream将字符串按空格分割成单词
istringstream iss1(line1);
istringstream iss2(line2);
// 使用unordered_map统计报纸中每个单词(字母排序后)的频率
unordered_map<string,int> freq;
string word;
while(iss1 >> word){
string sortedWord = word;
sort(sortedWord.begin(), sortedWord.end()); // 对单词中字母排序
freq[sortedWord]++;
}
bool flag = true;
// 遍历匿名信中的每个单词,尝试匹配报纸中的单词
while(iss2 >> word){
string sortedWord = word;
sort(sortedWord.begin(), sortedWord.end());
if(freq[sortedWord] > 0){
freq[sortedWord]--; // 扣减对应单词数量
} else {
flag = false;
break;
}
}
// 输出结果
cout << (flag ? "true" : "false") << endl;
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。