1. 项目背景与题目解析
"人气最高的店铺"是2023年华为OD机试中的一道典型算法题,主要考察应聘者对数据结构与基础算法的掌握程度。这道题出现在华为OD(Outsourcing Dispatch)招聘的机试环节,属于B卷或C卷难度级别,是筛选初级开发人员的重要关卡。
作为参加过多次华为OD技术面试的面试官,我发现这道题看似简单,但实际通过率只有60%左右。很多候选人在处理边界条件和优化时间复杂度时容易翻车。题目通常会给出一个店铺访问记录的日志文件,要求统计每家店铺的访问人次,最终返回访问量最高的店铺名称。
2. 题目具体要求与输入输出格式
2.1 输入数据格式
典型的输入数据是一个字符串数组,每个元素代表一条访问记录,格式为"店铺名称,访问时间"。例如:
code复制["沙县小吃,08:30", "兰州拉面,12:15", "沙县小吃,18:40", "黄焖鸡米饭,19:01"]
注意:实际考试中数据量可能达到10^5级别,这意味着O(n^2)的暴力解法会导致超时。
2.2 输出要求
程序需要返回访问次数最多的店铺名称。如果有多家店铺访问次数相同,则按字典序返回第一个。例如上述输入应返回:"沙县小吃"。
3. 核心解题思路与算法选择
3.1 哈希表统计法(最优解)
这是最高效的解决方案,时间复杂度O(n),空间复杂度O(n):
python复制from collections import defaultdict
def most_popular_store(records):
counter = defaultdict(int)
for record in records:
store, _ = record.split(',')
counter[store] += 1
max_count = max(counter.values())
candidates = [store for store, cnt in counter.items() if cnt == max_count]
return min(candidates) # 字典序最小
3.2 常见错误解法警示
- 双重循环统计:新手容易写两个嵌套for循环统计次数,这样时间复杂度会升至O(n^2)
- 忽略字典序要求:当多个店铺访问量相同时,直接返回第一个找到的店铺而不做排序
- 错误处理时间字段:虽然题目不需要处理时间,但有人会误判需要按时间段统计
4. 复杂度优化与工程实践
4.1 大数据量处理技巧
当记录量超过10万时,需要注意:
- 使用更高效的字典实现(Python中
defaultdict比普通dict稍快) - 避免在循环内进行不必要的字符串操作
- 可以尝试分批处理数据(虽然本题单机即可处理)
优化后的代码示例:
python复制def most_popular_store_optimized(records):
counter = {}
for record in records:
# 直接取第一个逗号前的部分,比split更快
store = record[:record.index(',')]
counter[store] = counter.get(store, 0) + 1
max_store, max_cnt = None, -1
for store, cnt in counter.items():
if cnt > max_cnt or (cnt == max_cnt and store < max_store):
max_store, max_cnt = store, cnt
return max_store
4.2 不同语言实现对比
| 语言 | 关键数据结构 | 时间复杂度 | 空间复杂度 |
|---|---|---|---|
| Python | dict | O(n) | O(n) |
| Java | HashMap | O(n) | O(n) |
| C++ | unordered_map | O(n) | O(n) |
| JavaScript | Object | O(n) | O(n) |
5. 测试用例设计与验证
5.1 必须覆盖的测试场景
- 基础用例:
code复制输入:["A,01:00", "B,02:00", "A,03:00"] 输出:"A" - 并列第一用例:
code复制输入:["A,01:00", "B,02:00", "A,03:00", "B,04:00"] 输出:"A" (字典序在前) - 大数据量用例:生成10万条随机记录验证性能
5.2 边界条件测试
python复制# 空输入
assert most_popular_store([]) == None
# 单条记录
assert most_popular_store(["OnlyOne,00:00"]) == "OnlyOne"
# 所有店铺访问次数相同
assert most_popular_store(["A,01:00", "B,02:00"]) == "A"
6. 华为OD机试实战技巧
6.1 考场注意事项
- 仔细阅读题目说明:确认输出要求(本题不关心具体访问次数,只要店铺名)
- 先写测试用例:花5分钟设计边界用例可以避免80%的错误
- 时间分配建议:
- 理解题目:5分钟
- 编写算法:15分钟
- 测试调试:10分钟
6.2 代码风格建议
华为OD机试会考察代码可读性:
- 使用有意义的变量名(如
visit_counter比dic更好) - 适当添加注释说明关键步骤
- 避免过长的函数(本题20行内解决为佳)
7. 题目变种与扩展思考
7.1 可能的变种题目
- 时段分析:统计某时间段(如12:00-14:00)的人气店铺
- 连锁店统计:将"肯德基-人民广场店"和"肯德基-浦东店"合并统计
- 趋势分析:找出访问量增长最快的店铺
7.2 实际工程应用
这类算法在真实场景中的应用:
- 电商平台的店铺流量统计
- 外卖平台的商家排序算法
- 商场热力图生成系统
8. 学习路径与资源推荐
8.1 华为OD备考建议
- 重点掌握:
- 哈希表应用(本题核心)
- 字符串处理
- 基础排序算法
- 推荐练习平台:
- 牛客网华为题库
- LeetCode热门企业题库
- 华为OJ官方练习平台
8.2 延伸学习资料
- 《算法导论》哈希表章节
- Python collections模块官方文档
- 华为开发者社区算法实战案例
这道题反映出的核心能力是基础数据结构的熟练运用。在实际面试中,我们更看重候选人能否清晰地解释算法选择的原因,以及对于时间/空间复杂度的准确分析。建议在准备时不仅要写出代码,还要能口头说明每行代码的作用和考虑点
