
2025 A卷 100分 题型
本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《告警抑制》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C
GO
更多内容
题目名称:告警抑制
- 知识点:字符串处理、哈希映射(逻辑处理)
- 时间限制:1秒
- 空间限制:256MB
- 限定语言:不限
题目描述
告警抑制是指高优先级告警抑制低优先级告警的规则。高优先级告警产生后,低优先级告警不再产生。请根据原始告警列表和告警抑制关系,给出实际产生的告警列表。
输入描述:
- 第一行为数字
N
,表示告警抑制关系个数(0 ≤ N ≤ 120)。 - 接下来
N
行,每行由空格分隔的两个告警ID(格式:大写字母+0或1个数字),例如A B
,表示A
抑制B
。 - 最后一行为告警产生列表,列表长度范围为 [1,100],告警ID间以空格分隔。
输出描述 :
真实产生的告警列表(未被抑制的告警),按输入顺序输出,ID间以空格分隔。
示例 :
输入:
2
A B
B C
A B C D E
输出:
A D E
解释:
A
抑制B
,B
抑制C
,因此B
和C
被抑制,最终输出A D E
。
补充规则:
- 无循环抑制 :不会出现
A→B→A
的循环关系。 - 无传递抑制 :例如
A→B→C
时,A
不直接抑制C
,但被抑制的B
仍可抑制C
。 - 位置无关:被抑制的告警无论在高优先级告警的前后,均被屏蔽。
Java
问题分析
我们需要根据给定的告警抑制关系和原始告警列表,输出实际产生的未被抑制的告警列表。高优先级告警会抑制低优先级告警,无论它们在输入列表中的顺序如何。
解题思路
- 建立抑制关系映射:记录每个告警被哪些高优先级告警抑制。
- 快速判断抑制存在性:通过集合快速检查某个告警是否存在于输入列表中。
- 遍历原始告警列表:对于每个告警,检查是否存在抑制它的告警存在于输入列表中,若存在则过滤,否则保留。
代码实现
java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = Integer.parseInt(scanner.nextLine()); // 读取抑制关系个数
// 建立抑制关系映射表:key是被抑制的告警,value是抑制它的告警集合
Map<String, Set<String>> suppressionMap = new HashMap<>();
for (int i = 0; i < N; i++) {
String[] parts = scanner.nextLine().split(" ");
String suppressor = parts[0]; // 抑制者,例如A
String suppressed = parts[1]; // 被抑制者,例如B
if (!suppressionMap.containsKey(suppressed)) {
suppressionMap.put(suppressed, new HashSet<>());
}
suppressionMap.get(suppressed).add(suppressor);
}
// 读取原始告警列表,并转换为集合用于快速查询
String[] alerts = scanner.nextLine().split(" ");
Set<String> inputSet = new HashSet<>(Arrays.asList(alerts));
List<String> result = new ArrayList<>(); // 保存未被抑制的告警
for (String alert : alerts) {
boolean isSuppressed = false;
// 检查当前告警是否有抑制者存在于输入列表中
if (suppressionMap.containsKey(alert)) {
for (String suppressor : suppressionMap.get(alert)) {
if (inputSet.contains(suppressor)) {
isSuppressed = true;
break;
}
}
}
if (!isSuppressed) {
result.add(alert); // 未被抑制,加入结果
}
}
// 按输入顺序输出结果
System.out.println(String.join(" ", result));
}
}
代码详细解析
- 读取抑制关系个数 :使用
scanner.nextLine()
读取第一行并转换为整数N
。 - 建立抑制关系映射 :
- 使用
HashMap
存储,键为被抑制的告警,值为抑制它的告警集合。 - 遍历
N
行,每行拆分为抑制者和被抑制者,将被抑制者作为键,抑制者添加到对应的集合。
- 使用
- 读取原始告警列表 :拆分为数组并转换为集合
inputSet
用于快速查询。 - 过滤被抑制的告警 :
- 遍历每个告警,检查是否存在抑制它的告警在
inputSet
中。 - 若存在,则跳过;否则加入结果列表。
- 遍历每个告警,检查是否存在抑制它的告警在
- 输出结果:按输入顺序拼接未被抑制的告警。
示例测试
示例1 :
输入:
2
A B
B C
A B C D E
输出:
A D E
解析:A 抑制 B,B 抑制 C,B 和 C 被过滤,D、E 无抑制。
示例2 :
输入:
1
B A
B A
输出:
B
解析:B 抑制 A,A 被过滤,B 被保留。
示例3 :
输入:
0
A B C
输出:
A B C
解析:无抑制关系,所有告警均保留。
综合分析
- 时间复杂度:O(N + M*K),其中 N 为抑制关系数,M 为告警列表长度,K 为每个告警的抑制者数量。高效处理最大数据规模。
- 空间复杂度:O(N + M),存储抑制关系和输入集合。
- 正确性:通过抑制关系映射和集合查询,确保所有抑制条件被正确判断。
- 适用性:处理所有合法输入,包括重复告警和不同顺序的抑制关系。
python
问题分析
我们需要根据给定的告警抑制关系和原始告警列表,输出实际产生的未被抑制的告警列表。高优先级告警会抑制低优先级告警,无论它们在输入列表中的顺序如何。
解题思路
- 建立抑制关系映射:记录每个告警被哪些高优先级告警抑制。
- 快速判断抑制存在性:通过集合快速检查某个告警是否存在于输入列表中。
- 遍历原始告警列表:对于每个告警,检查是否存在抑制它的告警存在于输入列表中,若存在则过滤,否则保留。
代码实现
python
from collections import defaultdict
def main():
n = int(input()) # 读取抑制关系个数
suppression = defaultdict(set) # 抑制关系映射表:被抑制的告警 → 抑制它的告警集合
# 读取所有抑制关系
for _ in range(n):
suppressor, suppressed = input().strip().split()
suppression[suppressed].add(suppressor)
# 读取原始告警列表,并保留原始顺序
alerts = input().strip().split()
existing_alerts = set(alerts) # 用于快速判断告警是否存在
result = []
for alert in alerts:
# 检查当前告警是否被抑制
is_suppressed = False
# 如果当前告警存在于抑制关系中
if alert in suppression:
# 遍历所有能抑制它的告警,判断是否存在于原始列表
for suppressor in suppression[alert]:
if suppressor in existing_alerts:
is_suppressed = True
break # 只要有一个抑制者存在即可跳过
if not is_suppressed:
result.append(alert)
print(' '.join(result))
if __name__ == "__main__":
main()
代码详细解析
-
读取输入:
n
:抑制关系数量。suppression
:使用defaultdict(set)
存储抑制关系。例如A B
表示B
被A
抑制,存入suppression['B'].add('A')
。
-
处理原始告警列表:
alerts
:保留原始顺序的告警列表。existing_alerts
:转换为集合用于快速查询。
-
过滤逻辑:
- 遍历每个告警
alert
。 - 如果该告警在抑制关系中(
suppression
字典中存在),检查其所有抑制者是否存在于existing_alerts
。 - 只要有一个抑制者存在,则当前告警被过滤。
- 遍历每个告警
-
输出结果:按原始顺序输出未被抑制的告警。
示例测试
示例1 :
输入:
2
A B
B C
A B C D E
输出:
A D E
解析:A
抑制 B
,B
抑制 C
,B
和 C
被抑制。
示例2 :
输入:
1
B A
B A
输出:
B
解析:B
抑制 A
,A
被过滤。
示例3 :
输入:
0
A B C
输出:
A B C
解析:无抑制关系,所有告警保留。
综合分析
-
时间复杂度:O(N + M*K)
N
是抑制关系数量,M
是告警列表长度,K
是每个告警的最大抑制者数量。- 集合查询和遍历抑制者的时间复杂度为 O(1) 和 O(K),总体高效。
-
空间复杂度:O(N + M)
- 存储抑制关系和原始告警列表。
-
正确性:
- 通过集合快速判断抑制者是否存在,确保所有抑制条件被正确检查。
-
适用性:
- 处理所有合法输入,包括重复告警和多级抑制关系。
JavaScript
问题分析
我们需要根据给定的告警抑制关系和原始告警列表,输出实际产生的未被抑制的告警列表。高优先级告警会抑制低优先级告警,无论它们在输入列表中的顺序如何。
解题思路
- 建立抑制关系映射:记录每个告警被哪些高优先级告警抑制。
- 快速判断抑制存在性:通过集合快速检查某个告警是否存在于输入列表中。
- 遍历原始告警列表:对于每个告警,检查是否存在抑制它的告警存在于输入列表中,若存在则过滤,否则保留。
代码实现
javascript
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let n; // 抑制关系数量
let lineCount = 0;
const suppressionMap = {}; // 抑制关系表:{ 被抑制的告警: Set(抑制者) }
let originalAlerts; // 原始告警列表
rl.on('line', (line) => {
if (lineCount === 0) { // 第一行读取N
n = parseInt(line);
lineCount++;
} else if (lineCount <= n) { // 读取N行抑制关系
const [suppressor, suppressed] = line.trim().split(' ');
if (!suppressionMap[suppressed]) {
suppressionMap[suppressed] = new Set();
}
suppressionMap[suppressed].add(suppressor);
lineCount++;
} else { // 最后一行读取原始告警列表
originalAlerts = line.trim().split(' ');
rl.close();
}
});
rl.on('close', () => {
const existingAlerts = new Set(originalAlerts); // 原始告警集合(快速查询)
const result = [];
for (const alert of originalAlerts) {
let isSuppressed = false;
if (suppressionMap[alert]) { // 检查当前告警是否被抑制
// 遍历所有抑制者,判断是否存在于原始列表
for (const suppressor of suppressionMap[alert]) {
if (existingAlerts.has(suppressor)) {
isSuppressed = true;
break;
}
}
}
if (!isSuppressed) {
result.push(alert); // 未被抑制,加入结果
}
}
console.log(result.join(' '));
});
代码详细解析
-
输入处理:
- 使用
readline
逐行读取输入,第一行解析为抑制关系数量n
。 - 后续
n
行解析为抑制关系,存入suppressionMap
对象,键为被抑制的告警,值为抑制者的集合。 - 最后一行读取原始告警列表,转换为数组
originalAlerts
。
- 使用
-
抑制关系映射:
javascriptif (!suppressionMap[suppressed]) { suppressionMap[suppressed] = new Set(); } suppressionMap[suppressed].add(suppressor);
- 若被抑制的告警不存在于映射表,初始化其对应的集合。
- 将抑制者添加到被抑制告警的集合中。
-
过滤逻辑:
javascriptconst existingAlerts = new Set(originalAlerts); // 快速查询集合 for (const alert of originalAlerts) { if (suppressionMap[alert]) { // 当前告警可能被抑制 for (const suppressor of suppressionMap[alert]) { if (existingAlerts.has(suppressor)) { // 抑制者存在 isSuppressed = true; break; } } } if (!isSuppressed) result.push(alert); }
- 遍历原始告警列表,检查每个告警是否被抑制。
- 若存在抑制者存在于原始列表中,过滤该告警;否则保留。
示例测试
示例1 :
输入:
2
A B
B C
A B C D E
输出:
A D E
解析:A 抑制 B,B 抑制 C,B 和 C 被过滤。
示例2 :
输入:
1
B A
B A
输出:
B
解析:B 抑制 A,A 被过滤。
示例3 :
输入:
0
A B C
输出:
A B C
解析:无抑制关系,所有告警保留。
综合分析
-
时间复杂度:O(N + M*K)
N
是抑制关系数量,M
是告警列表长度,K
是每个告警的抑制者数量。- 集合查询时间为 O(1),遍历抑制关系的时间为 O(K)。
-
空间复杂度:O(N + M)
- 存储抑制关系和原始告警列表。
-
正确性:
- 通过集合快速判断抑制者是否存在,确保所有抑制条件被正确过滤。
-
适用性:
- 处理所有合法输入,包括重复告警和多级抑制关系。
C++
问题分析
我们需要根据给定的告警抑制关系和原始告警列表,输出实际产生的未被抑制的告警列表。高优先级告警会抑制低优先级告警,无论它们在输入列表中的顺序如何。
解题思路
- 建立抑制关系映射:记录每个告警被哪些高优先级告警抑制。
- 快速判断抑制存在性:通过集合快速检查某个告警是否存在于输入列表中。
- 遍历原始告警列表:对于每个告警,检查是否存在抑制它的告警存在于输入列表中,若存在则过滤,否则保留。
代码实现
cpp
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
using namespace std;
int main() {
// 读取抑制关系数量
string line;
getline(cin, line);
int N = stoi(line);
// 建立抑制关系映射表:key是被抑制的告警,value是抑制它的告警集合
unordered_map<string, unordered_set<string>> suppressionMap;
for (int i = 0; i < N; ++i) {
getline(cin, line);
istringstream iss(line);
string suppressor, suppressed;
iss >> suppressor >> suppressed;
suppressionMap[suppressed].insert(suppressor);
}
// 读取原始告警列表并存入集合和数组
getline(cin, line);
istringstream iss_alerts(line);
vector<string> alerts;
unordered_set<string> alertSet;
string alert;
while (iss_alerts >> alert) {
alerts.push_back(alert);
alertSet.insert(alert);
}
// 过滤被抑制的告警
vector<string> result;
for (const string& a : alerts) {
bool isSuppressed = false;
if (suppressionMap.find(a) != suppressionMap.end()) {
for (const string& suppressor : suppressionMap[a]) {
if (alertSet.count(suppressor)) {
isSuppressed = true;
break;
}
}
}
if (!isSuppressed) {
result.push_back(a);
}
}
// 输出结果
for (size_t i = 0; i < result.size(); ++i) {
if (i > 0) cout << " ";
cout << result[i];
}
cout << endl;
return 0;
}
代码详细解析
-
读取抑制关系数量:
- 使用
getline
读取第一行并转换为整数N
。
- 使用
-
建立抑制关系映射:
- 使用
unordered_map
存储,键为被抑制的告警,值为抑制者的集合。 - 逐行读取抑制关系,将被抑制的告警作为键,抑制者添加到对应的集合。
- 使用
-
处理原始告警列表:
- 读取原始告警列表,存入
alerts
数组(保留顺序)和alertSet
集合(快速查询)。
- 读取原始告警列表,存入
-
过滤逻辑:
- 遍历每个告警,检查是否存在抑制者存在于
alertSet
中。 - 若存在,则跳过;否则保留该告警。
- 遍历每个告警,检查是否存在抑制者存在于
-
输出结果:
- 按原始顺序输出未被抑制的告警,用空格分隔。
示例测试
示例1 :
输入:
2
A B
B C
A B C D E
输出:
A D E
解析:A 抑制 B,B 抑制 C,B 和 C 被过滤。
示例2 :
输入:
1
B A
B A
输出:
B
解析:B 抑制 A,A 被过滤。
示例3 :
输入:
0
A B C
输出:
A B C
解析:无抑制关系,所有告警保留。
综合分析
-
时间复杂度:O(N + M*K)
N
是抑制关系数量,M
是告警列表长度,K
是每个告警的抑制者数量。- 集合查询时间为 O(1),遍历抑制关系的时间为 O(K)。
-
空间复杂度:O(N + M)
- 存储抑制关系和原始告警列表。
-
正确性:
- 通过集合快速判断抑制者是否存在,确保所有抑制条件被正确检查。
-
适用性:
- 处理所有合法输入,包括重复告警和多级抑制关系。
C
问题分析
我们需要根据给定的告警抑制关系和原始告警列表,输出实际产生的未被抑制的告警列表。高优先级告警会抑制低优先级告警,无论它们在输入列表中的顺序如何。关键在于高效存储抑制关系并快速判断告警是否被抑制。
解题思路
- 输入处理:读取抑制关系并构建数据结构,保存每个告警的抑制者列表。
- 原始告警存储:将原始告警保存到数组以便按顺序输出,同时支持快速存在性检查。
- 过滤逻辑:遍历每个告警,检查其是否被列表中的任一抑制者抑制。
- 输出结果:按顺序输出未被抑制的告警。
代码实现
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 抑制者链表节点
typedef struct SuppressorNode {
char suppressor[32];
struct SuppressorNode *next;
} SuppressorNode;
// 抑制关系条目:被抑制的告警及其抑制者链表
typedef struct {
char suppressed[32];
SuppressorNode *sup_list;
} SuppressionEntry;
SuppressionEntry suppression_entries[120]; // 最大抑制关系数
int num_suppression_entries = 0;
// 判断字符串是否存在于原始告警列表中
bool is_exist(char *str, char **alerts, int alert_count) {
for (int i = 0; i < alert_count; i++) {
if (strcmp(str, alerts[i]) == 0) {
return true;
}
}
return false;
}
int main() {
int N;
char line[1024];
// 读取抑制关系数量
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &N);
// 读取抑制关系并构建数据结构
for (int i = 0; i < N; i++) {
fgets(line, sizeof(line), stdin);
char suppressor[32], suppressed[32];
sscanf(line, "%s %s", suppressor, suppressed);
// 查找是否已有对应的被抑制条目
bool found = false;
for (int j = 0; j < num_suppression_entries; j++) {
if (strcmp(suppression_entries[j].suppressed, suppressed) == 0) {
// 添加抑制者到链表头部
SuppressorNode *node = (SuppressorNode *)malloc(sizeof(SuppressorNode));
strcpy(node->suppressor, suppressor);
node->next = suppression_entries[j].sup_list;
suppression_entries[j].sup_list = node;
found = true;
break;
}
}
if (!found) {
// 新增条目
strcpy(suppression_entries[num_suppression_entries].suppressed, suppressed);
SuppressorNode *node = (SuppressorNode *)malloc(sizeof(SuppressorNode));
strcpy(node->suppressor, suppressor);
node->next = NULL;
suppression_entries[num_suppression_entries].sup_list = node;
num_suppression_entries++;
}
}
// 读取原始告警列表
fgets(line, sizeof(line), stdin);
char *alerts[100];
int alert_count = 0;
char *token = strtok(line, " \n");
while (token != NULL && alert_count < 100) {
alerts[alert_count] = strdup(token); // 复制字符串
alert_count++;
token = strtok(NULL, " \n");
}
// 过滤被抑制的告警
char *result[100];
int result_count = 0;
for (int i = 0; i < alert_count; i++) {
char *current = alerts[i];
bool is_suppressed = false;
// 检查当前告警是否被抑制
for (int j = 0; j < num_suppression_entries; j++) {
if (strcmp(suppression_entries[j].suppressed, current) == 0) {
// 遍历抑制者链表,判断是否存在
SuppressorNode *node = suppression_entries[j].sup_list;
while (node != NULL) {
if (is_exist(node->suppressor, alerts, alert_count)) {
is_suppressed = true;
break;
}
node = node->next;
}
if (is_suppressed) break;
}
}
if (!is_suppressed) {
result[result_count++] = current;
}
}
// 输出结果
for (int i = 0; i < result_count; i++) {
if (i > 0) printf(" ");
printf("%s", result[i]);
}
printf("\n");
// 释放内存
for (int i = 0; i < alert_count; i++) {
free(alerts[i]);
}
for (int i = 0; i < num_suppression_entries; i++) {
SuppressorNode *node = suppression_entries[i].sup_list;
while (node != NULL) {
SuppressorNode *temp = node;
node = node->next;
free(temp);
}
}
return 0;
}
代码详细解析
-
数据结构定义:
SuppressorNode
:链表节点,存储抑制者ID。SuppressionEntry
:被抑制的告警及其抑制者链表。
-
读取抑制关系:
- 每行拆分为抑制者和被抑制者。
- 若被抑制的告警已存在,将抑制者添加到链表头部;否则创建新条目。
-
原始告警处理:
- 使用
strtok
分割输入行,保存到alerts
数组,并复制字符串(strdup
)。
- 使用
-
过滤被抑制告警:
- 遍历每个告警,检查其是否在抑制关系中。
- 若存在抑制关系,遍历抑制者链表,判断是否存在原始列表中。
-
输出结果:
- 按顺序输出未被抑制的告警。
-
内存释放:
- 释放动态分配的告警字符串和抑制者链表节点。
示例测试
示例1 :
输入:
2
A B
B C
A B C D E
输出:
A D E
解析:A抑制B,B抑制C,B和C被过滤。
示例2 :
输入:
1
B A
B A
输出:
B
解析:B抑制A,A被过滤。
示例3 :
输入:
0
A B C
输出:
A B C
解析:无抑制关系,所有告警保留。
综合分析
-
时间复杂度:
- 读取抑制关系:O(N),N为抑制关系数。
- 过滤告警:O(M*K),M为告警列表长度,K为抑制者数量。
- 总体时间复杂度为O(N + M*K),适用于题目限制。
-
空间复杂度:
- 存储抑制关系和原始告警列表,空间复杂度为O(N + M)。
-
正确性:
- 通过链表和线性查找确保所有抑制关系被正确处理。
-
适用性:
- 处理所有合法输入,包括循环抑制和传递抑制(但题目规定不存在)。
GO
问题分析
我们需要根据告警抑制关系和原始告警列表,过滤掉所有被抑制的告警,输出未被抑制的告警。高优先级告警会抑制所有直接关联的低优先级告警,无论其顺序如何。关键在于快速判断某个告警是否被其他告警抑制。
解题思路
- 存储抑制关系:使用嵌套字典记录每个告警的抑制者集合。
- 快速存在性检查:将原始告警存入集合,以便快速判断抑制者是否存在。
- 遍历过滤:对于每个告警,检查其是否有抑制者存在于原始列表中,若存在则过滤。
代码实现
go
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// 读取抑制关系数量
scanner.Scan()
var n int
fmt.Sscanf(scanner.Text(), "%d", &n)
// 初始化抑制关系映射:被抑制告警 → 抑制者集合
suppression := make(map[string]map[string]struct{})
// 读取并存储抑制关系
for i := 0; i < n; i++ {
scanner.Scan()
parts := strings.Split(scanner.Text(), " ")
if len(parts) != 2 {
continue // 跳过格式错误行
}
suppressor, suppressed := parts[0], parts[1]
if _, ok := suppression[suppressed]; !ok {
suppression[suppressed] = make(map[string]struct{})
}
suppression[suppressed][suppressor] = struct{}{}
}
// 读取原始告警列表并构建存在集合
scanner.Scan()
alerts := strings.Fields(scanner.Text())
existing := make(map[string]struct{})
for _, a := range alerts {
existing[a] = struct{}{}
}
// 过滤被抑制的告警
var result []string
for _, a := range alerts {
suppressed := false
// 检查当前告警是否有抑制者在原始列表中
if suppressors, ok := suppression[a]; ok {
for s := range suppressors {
if _, exists := existing[s]; exists {
suppressed = true
break
}
}
}
if !suppressed {
result = append(result, a)
}
}
// 输出结果
fmt.Println(strings.Join(result, " "))
}
代码详细解析
-
读取抑制关系数量:
- 使用
bufio.Scanner
读取输入的第一行,解析为整数n
。
- 使用
-
存储抑制关系:
- 使用嵌套字典
suppression
,外层键为被抑制告警,内层键为抑制者集合。 - 每行抑制关系拆分为抑制者(
suppressor
)和被抑制者(suppressed
),存入字典。
- 使用嵌套字典
-
处理原始告警列表:
- 将原始告警存入切片
alerts
以保留顺序。 - 使用字典
existing
存储所有原始告警,以便 O(1) 时间存在性检查。
- 将原始告警存入切片
-
过滤逻辑:
- 遍历每个原始告警
a
。 - 若
a
存在于suppression
中,遍历其所有抑制者,检查是否存在于existing
。 - 若存在任一抑制者,则
a
被抑制,否则保留。
- 遍历每个原始告警
-
输出结果:
- 使用
strings.Join
按原始顺序拼接未被抑制的告警。
- 使用
示例测试
示例1 :
输入:
2
A B
B C
A B C D E
输出:
A D E
解析:A 抑制 B,B 抑制 C。B 和 C 被过滤。
示例2 :
输入:
1
B A
B A
输出:
B
解析:B 抑制 A,A 被过滤。
示例3 :
输入:
0
A B C
输出:
A B C
解析:无抑制关系,全部保留。
综合分析
-
时间复杂度:
- 读取输入:O(N + M),N 为抑制关系数,M 为原始告警数。
- 过滤过程:O(M*K),K 为每个告警的抑制者数量。每个告警的抑制者检查为 O(1)。
-
空间复杂度:
- 抑制关系存储:O(N),每个抑制关系存储一次。
- 原始告警存储:O(M),存储列表和集合。
-
正确性:
- 通过直接检查抑制者是否存在于原始列表,确保所有抑制关系被正确处理。
-
适用性:
- 处理大规模数据高效,适用于题目给出的最大输入限制。
更多内容:
https://www.kdocs.cn/l/cvk0eoGYucWA
本文发表于【纪元A梦】,关注我,获取更多实用教程/资源!