news 2026/7/31 10:42:22

​从454. 四数相加 II 中学到Counter​

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
​从454. 四数相加 II 中学到Counter​

从454. 四数相加 II 中学到Counter,我们使用哈希表(Counter将时间复杂度从暴力的 (O(n^4)) 优化到 (O(n^2))。


一、Counter的内部数据结构

Counter是什么?

  • Counter是 Python 标准库collections模块中的一个字典子类(dict subclass)
  • 它专门用于计数可哈希对象
  • 底层实现就是哈希表(hash table),和普通dict一样,基于开放寻址或链地址法(CPython 中是开放寻址)。

🔧 内部结构示例

from collections import Counter cnt = Counter(['a', 'b', 'a', 'c', 'b', 'a']) print(cnt) # 输出: Counter({'a': 3, 'b': 2, 'c': 1})

其内部存储等价于:

{'a': 3, 'b': 2, 'c': 1}
  • 键(key):元素(必须可哈希,如 int、str、tuple)
  • 值(value):该元素出现的次数(int)

💡 所以Counter插入、查询、更新操作平均时间复杂度都是O(1)


二、code 中Counter的实例分析

cnt = Counter(x + y for x in nums1 for y in nums2)

📌 这行做了什么?

  • 遍历nums1nums2的所有组合(共 (n^2) 对)
  • 计算每对的和s = x + y
  • 统计每个和s出现的次数

🧪 举个具体例子

假设:

nums1 = [1, 2] nums2 = [-2, -1]

那么x + y的所有可能为:

  • 1 + (-2) = -1
  • 1 + (-1) = 0
  • 2 + (-2) = 0
  • 2 + (-1) = 1

所以:

cnt = Counter({0: 2, -1: 1, 1: 1})

即:

cnt[-1] == 1 cnt[0] == 2 cnt[1] == 1 cnt[999] == 0 # 不存在的键返回 0(这是 Counter 的特性!)

✅ 关键优势:访问不存在的键不会报错,而是返回 0,这正是你代码中cnt[-x-y]安全的原因!


三、完整执行流程示例

输入:

nums1 = [1, 2] nums2 = [-2, -1] nums3 = [-1, 2] nums4 = [0, 2]

目标:找满足a + b + c + d == 0的元组数量。

Step 1: 构建cnt(a + b 的频次)

a+b: 1 + (-2) = -1 1 + (-1) = 0 2 + (-2) = 0 2 + (-1) = 1 cnt = {-1:1, 0:2, 1:1}

Step 2: 遍历c + d,查- (c + d)是否在cnt

c+d: -1 + 0 = -1 → 需要 a+b = 1 → cnt[1] = 1 -1 + 2 = 1 → 需要 a+b = -1 → cnt[-1] = 1 2 + 0 = 2 → 需要 a+b = -2 → cnt[-2] = 0 2 + 2 = 4 → 需要 a+b = -4 → cnt[-4] = 0 总和 = 1 + 1 + 0 + 0 = 2

✅ 返回2,正确。


四、为什么用Counter而不是普通dict

你可以用普通dict,但需要手动处理默认值:

# 手动写法(不推荐) d = {} for x in nums1: for y in nums2: d[x+y] = d.get(x+y, 0) + 1 total = 0 for x in nums3: for y in nums4: total += d.get(-(x+y), 0)

Counter自动处理缺失键为 0,代码更简洁安全:

# 你的写法(推荐) cnt = Counter(x+y for x in nums1 for y in nums2) return sum(cnt[-x-y] for x in nums3 for y in nums4)

✅ 这正是Counter在此场景下的最大价值!


五、复杂度分析

步骤时间空间
构建cnt(O(n^2))(O(n^2))(最坏所有和都不同)
遍历nums3+nums4(O(n^2))(O(1))
总计(O(n^2))(O(n^2))

远优于暴力 (O(n^4))。


总结

  • Counter基于哈希表的字典子类,用于计数。
  • 在你的代码中,它存储了nums1 + nums2所有可能和的出现次数
  • 利用Counter访问不存在键返回 0的特性,使得cnt[-x-y]安全且简洁。
  • 整体算法是空间换时间的典型应用,将四重循环降为两个双重循环。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/29 18:09:36

耐用折叠屏手机推荐:三星Galaxy Z TriFold如何破解“折痕与耐用”难题?

当折叠屏手机从概念产品走向大众市场,消费者最关心的问题之一就是耐用性。毕竟,折叠屏设备多出了复杂的机械结构和柔性屏幕,这些部件在日常使用中面临更多挑战。那么,如今的折叠屏手机在耐用性方面达到了什么水平?三星…

作者头像 李华
网站建设 2026/7/28 13:04:19

前端技术风险防控:以防为主,防控结合

前端技术风险防控:以防为主,防控结合 1. 核心理念:防与控的辩证关系 防:在风险发生前,通过技术手段、流程规范、架构设计等主动预防,从根源上减少风险发生的概率。 控:当风险不可避免地发生时&a…

作者头像 李华
网站建设 2026/7/31 1:47:56

入门大模型必知的100个基础问题(附简明答案)

写在前面 这篇内容将图片中的要点按顺序整理为「100 个基础问题 简明答案」。你可以把它当作查阅清单:从概念、结构、训练、评估到优化与应用,快速过一遍大模型(LLM)最常见的知识点。 100个基础问题什么是大模型? 答案…

作者头像 李华
网站建设 2026/7/30 4:27:27

vue基于Spring Boot的建筑材料管理系统的应用和研究_ug8y52z3

目录具体实现截图项目介绍论文大纲核心代码部分展示项目运行指导结论源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作具体实现截图 本系统(程序源码数据库调试部署讲解)同时还支持java、ThinkPHP、Node.js、Spring B…

作者头像 李华
网站建设 2026/7/30 2:07:19

【大模型】-LangChain--RAG文档系统

文章目录1.完整代码2.结果展示3. RAG介绍1.完整代码 由于使用的是通义,所以代码改造了下,因为openAI需要钱 import streamlit as st import tempfile import osfrom langchain_classic.memory import ConversationBufferMemory from langchain_communi…

作者头像 李华