title: 2026-01-19-牛客每日一题-阅读理解
date: 2026-01-19
tags:
- 算法学习
- 牛客
- 哈希
题目信息
- 平台:牛客
- 题目:阅读理解
- 难度:简单
- 题目链接
题目描述
给定 n 篇文章,每篇文章包含若干单词。随后有 m 次查询,每次给出一个单词,需要输出所有包含该单词的文章编号(按从小到大),若不存在则输出空行。
初步思路
- 预处理阶段用哈希表建立"单词 -> 出现的文章编号列表"。
- 每篇文章内重复单词只记录一次,避免同一编号重复输出。
- 查询时直接从哈希表取出列表并输出。
算法分析
- 核心:用哈希表存倒排索引,查询时 O(1) 均摊取答案
- 技巧:同一篇文章中去重,避免重复编号
- 时间复杂度:O(总单词数 + 总查询数)
- 空间复杂度:O(不同单词数 + 索引长度)
代码实现(C++)
cpp
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
unordered_map<string, vector<int>> positions;
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
int len;
cin >> len;
while (len--) {
string str;
cin >> str;
auto &v = positions[str];
if (v.empty() || v.back() != i) v.push_back(i);
}
}
int m;
cin >> m;
while (m--) {
string str;
cin >> str;
auto it = positions.find(str);
if (it == positions.end()) {
cout << '\n';
continue;
}
const auto &v = it->second;
for (int k = 0; k < (int)v.size(); ++k) {
if (k) cout << ' ';
cout << v[k];
}
cout << '\n';
}
return 0;
}
测试用例
| 输入 | 输出 | 说明 |
|---|---|---|
| n=2; 1: a b a; 2: b c; 查询 a, b, d | a -> 1; b -> 1 2; d -> 空行 | a 在第 1 篇,b 在第 1/2 篇,d 不存在 |
总结与反思
- 构建倒排索引可以把多次查询降到均摊 O(1)。
- 同一篇文章内去重是关键,否则会输出重复编号。