当前位置: 首页 > article >正文

如果给你10亿条id数据让你去重,你会怎么做?

如果给你10亿条id数据让你去重你会怎么做最近在刷一些其他题库的题发现遇到一些类似的问题甚至是相同的题还是会卡住我觉得我需要转变一下思路总结一下一类题的算法而不是每天写一道题的解题思路不然的话之前解题时卡在哪里后面遇到还是会卡在哪里。题目分析说到数组去重大家第一时间想到的就是Set 去重或者利用 Map 或 对象属性 key 的唯一性去重但是这道题10亿条数据如果存储为 Set 或者 Map 直接会内存溢出一些常规的遍历去重都会失效面对这样的大量数据去重如果数组本身是有序的我们可以用快慢指针去重如果是乱序的那我们需要用到位图法 (Bitmap)和布隆过滤器 (Bloom Filter)。ok接下来我们就来讲讲数组的去重吧。数组去重我们先来列举一下数组去重的通用方法Set 去重filter 去重利用 Map 或 对象属性 key 的唯一性去重快慢指针去重计数法/桶映射位图法 (Bitmap)布隆过滤器 (Bloom Filter)Set 去重原理这个应该目前最常用、最简洁的去重方法Set 是一种不允许重复值的数据结构。我们可以直接将原数组作为构造器的参数传递给 Set 再将 Set 转回成数组就能完成去重时间复杂度O(n)空间复杂度O(n)functionremoveDuplicates(arr){return[...newSet(arr)];}filter 去重原理利用indexOf总是返回元素第一次出现索引的特性。时间复杂度O(n2)空间复杂度O(1)functionremoveDuplicates(arr){returnarr.filter((item,index)arr.indexOf(item)index);}利用 Map 或 对象属性 key 的唯一性去重原理利用 Map 或 对象属性 key 的唯一性遍历数组将数组元素作为 key 添加到 Map 或者 对象中遇到重复 key 值可以不操作也可以做计数操作。这种方法其实跟 Set 去重原理相似但是直接传递数组给 Set 它内部一次性迭代整个可迭代对象引擎可以做优化这样性能更高但是自己遍历的话可以在循环中自己添加一些其他的逻辑这样更灵活。functionremoveDuplicates(arr){constmapnewMap();arr.forEach(item{if(!map.has(item)){map.set(item,1);}else{map.set(item,map.get(item)1);// 如果需要统计重复次数可以在这里更新计数}});returnArray.from(map.keys());}排序去重 快慢指针去重原理先对数组进行排序如快排或归并排序然后通过快慢指针Double Pointers遍历。如果arr[i] ! arr[i-1]则它是唯一的。如果不想开辟额外的空间或者数组本身是有序的就可以采用这种方法所以如果这10亿的数据本身是有序的那这种方法就是最优解。如果是乱序的数组我们需要加上排序本身的时间复杂但是如果你一些情况下它依旧是最稳妥的方法。时间复杂度O (n log n)空间复杂度O (1)原地修改functionremoveDuplicates(arr){if(arr.length0)return[];arr.sort();// 先排序for(leti1;iarr.length;i){if(arr[i]arr[i-1]){arr.splice(i,1);i--;// 删除后需要调整索引}}}计数法/桶映射原理创建一个长度覆盖数据范围的数组桶值出现时在对应下标处计数。这种方法适用于整数类型的数组因为数组的下标必须要是 0的整数面对其他类型的数组我们也可以使用统一的方法映射成数字但是如果数值范围过大就不适用了。时间复杂度O(n k) k 是数据的取值范围 空间复杂度O (n)// 假设元素范围 1 - 10000functionremoveDuplicates(arr){constcountnewArray(10001).fill(false);// 创建一个布尔数组来记录出现过的元素constresult[];for(leti0;iarr.length;i){if(arr[i]1arr[i]10000){// 确保元素在范围内count[arr[i]]true;// 标记出现过的元素}}for(leti1;i10000;i){if(count[i]){result.push(i);}}returnresult;}位图法 (Bitmap)这其实是针对计数法空间上的优化我们既然能够将其他类型的元素映射成数字那么我们也可以将数字映射成更小的值。原理使用每一“位”Bit来表示一个数字是否存在。时间复杂度O(n)空间复杂度O(k / 8) k 是数据的取值范围如果 10 亿数据是连续或范围可控的正整数例如用户 ID、手机号位图是唯一能实现 “既精确又省空间” 的方法。JavaScript 原生是没有位图数据结构的我们需要自己写一个classBitmap{constructor(size){this.sizesize;this.bitmapnewUint8Array(Math.ceil(size/8));// 使用 Uint8Array 来存储位图}setBit(index){constbyteIndexMath.floor(index/8);constbitIndexindex%8;this.bitmap[byteIndex]|(1bitIndex);// 设置对应位}getBit(index){constbyteIndexMath.floor(index/8);constbitIndexindex%8;return(this.bitmap[byteIndex](1bitIndex))!0;// 检查对应位是否被设置}}functionremoveDuplicates(arr){constbitmapnewBitmap(10000);constresult[];for(leti0;iarr.length;i){if(arr[i]1arr[i]10000){// 确保元素在范围内if(!bitmap.getBit(arr[i])){// 如果位图中没有设置该元素bitmap.setBit(arr[i]);// 设置该元素的位result.push(arr[i]);// 将该元素添加到结果数组中}}}returnresult;}布隆过滤器 (Bloom Filter)原理将元素通过多个哈希函数映射到位图的多个位置。如果所有位置都为1说明该元素“可能”已存在。时间复杂度O(n)空间复杂度O(m) m 比特数组的长度如果要追求极致速度且不在乎一点误差就可以选用这种方法。classBloomFilter{constructor(size1024,hashCount3){this.sizesize;// 位数组的大小bitthis.hashCounthashCount;// 哈希函数的数量// 使用 Uint8Array每个元素占 8 位所以长度除以 8this.bitArraynewUint8Array(Math.ceil(size/8));}// 添加元素add(item){consthashesthis._getHashes(item);hashes.forEach(hash{constbitPoshash%this.size;constarrayIdxMath.floor(bitPos/8);constbitIdxbitPos%8;// 将对应位置为 1this.bitArray[arrayIdx]|(1bitIdx);});}// 查询元素是否存在has(item){consthashesthis._getHashes(item);returnhashes.every(hash{constbitPoshash%this.size;constarrayIdxMath.floor(bitPos/8);constbitIdxbitPos%8;// 检查对应位是否为 1return(this.bitArray[arrayIdx](1bitIdx))!0;});}// 简单的哈希生成逻辑实际生产建议用 MurmurHash 等_getHashes(item){consthashes[];conststrString(item);for(leti0;ithis.hashCount;i){// 模拟不同的哈希函数通过给字符串加盐并进行简单的位运算lethash0;constsaltedStrstri;for(letj0;jsaltedStr.length;j){hash(hash5)-hashsaltedStr.charCodeAt(j);hash|0;// 强制转为 32 位整数}hashes.push(Math.abs(hash));}returnhashes;}}functionremoveDuplicates(arr){constbloomFilternewBloomFilter(1024,3);// 创建一个布隆过滤器constresult[];for(leti0;iarr.length;i){if(!bloomFilter.has(arr[i])){// 如果布隆过滤器中没有该元素bloomFilter.add(arr[i]);// 将该元素添加到布隆过滤器中result.push(arr[i]);// 将该元素添加到结果数组中}}returnresult;}这个方法空间性能平衡极佳但是会有极低概率的误判可能会把一个没见过的元素误判为见过详细原理:布隆过滤器结构一个 bit 数组 k 个哈希函数插入元素 x对 x 做 k 次哈希得到 k 个位置把这 k 个 bit 都置为 1查询元素 y同样算 k 个哈希位置如果所有位置都是 1→ 判定 y 存在只要有一个是 0 → 判定 y 不存在误判场景:元素y 实际不存在但之前插入的其他元素刚好把 y 对应的 k 个 bit 位全都覆盖成 1 了布隆过滤器只能看到 bit 是 1不知道是谁置的于是误判 y 存在布隆过滤器的性能取决于哈希函数的质量和数量哈希函数数量太少误报率高冲突多哈希函数数量太多位数组迅速填满性能下降。所以选择size和hashCount就很重要了需要根据预期的数据量 ( n )和可接受的误报率( p )来计算注意的 JS 是单线程的计算大量哈希值会阻塞事件循环。在大规模场景下通常将此逻辑放在Worker中。哈希分片最后提一嘴哈希分片哈希分片Hash Sharding并不属于一种独立的 “去重算法” 而是一种处理大规模数据的“分治策略”Divide and Conquer。如果把普通的去重比作 “在碗里挑出重复的豆子” 哈希分片就是“因为豆子太多一碗装不下所以先把豆子分装到不同的碗里并保证相同的豆子一定在同一个碗里”。如果内存不够用就可以将数据进行分片再在各个片段中执行去重操作就 ok 了。

相关文章:

如果给你10亿条id数据让你去重,你会怎么做?

如果给你10亿条id数据让你去重,你会怎么做? 最近在刷一些其他题库的题,发现遇到一些类似的问题甚至是相同的题还是会卡住,我觉得我需要转变一下思路,总结一下一类题的算法,而不是每天写一道题的解题思路&am…...

算法可视化神器!用动画让冒泡排序、二分查找一目了然

还在为理解冒泡排序的每一趟交换,或是二分查找的边界条件而绞尽脑汁吗?静态的代码和文字描述有时确实不够直观。 想要真正让算法“动”起来,一目了然?强烈推荐你试试**图码这个专注于算法可视化**的神器。 它提供了超过60种数据…...

Redis持久化:从AOF到RDB,如何实现数据不丢失?谑

Qt是一个跨平台C图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本笔记将重点介绍QSpinBox数值微调组件的常用方法及灵活应用。…...

AspNet MVC4 教学:AspNet MVC4 页面动态生成演示

HomeControllers.cs文件内容:using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc;namespace MvcDynamicPage.Controllers {public class HomeController : Controller{//// GET: /Home/public ActionResult Index(){…...

打字不如说话,说话不如截图——AI 代码助手的多模态输入实践仝

整体排查思路 我们的目标是验证以下三个环节是否正常: 登录成功时:服务器是否正确生成了Session并返回了包含正确 JSESSIONID的Cookie给浏览器。 浏览器端:浏览器是否成功接收并存储了该Cookie。 后续请求:浏览器在执行查询等操作…...

挂起、阻塞、锁和cpu占用

Thread.sleep() 和 Object.wait() 在 Java 多线程编程中,Thread.sleep() 和 Object.wait() 都能让线程暂停执行,但它们的目的机制和使用场景有本质区别。‌核心区别总结‌‌所属类不同‌sleep() 是 ‌Thread 类的静态方法‌,作用于当前线程。…...

【算法日记】Day 11 动态规划专题——区间DP之基于范围中划分点的讨论

Abstract:#动态规划 #区间DP #多边形剖分 1. 题目 题目:LeetCode 1039. 多边形三角剖分的最低得分核心思路:定义dp[i][j]表示从顶点i到顶点j构成的多边形(凸多边形,顶点按顺序排列)通过三角剖分能得到的最…...

TensorBoard日志可视化翻车实录:从端口占用、缓存问题到库版本冲突的完整排错指南

TensorBoard故障排查实战手册:从端口冲突到版本兼容的深度解决方案 TensorBoard作为深度学习实验可视化的核心工具,其使用过程中遇到的各类"玄学问题"往往让开发者束手无策。本文将系统梳理那些官方文档未曾详述的典型故障场景,提供…...

YOLO-v8.3保姆级教程:手把手教你搭建工业质检系统

YOLO-v8.3保姆级教程:手把手教你搭建工业质检系统 1. 引言 在工业生产线上,产品质量检测一直是至关重要的环节。传统的人工质检方式不仅效率低下,而且容易受到主观因素影响,导致漏检和误检。随着计算机视觉技术的发展&#xff0…...

别再死记Twist公式了!用‘拧螺丝’的直觉理解机器人运动学(附Python可视化代码)

从拧螺丝到机器人运动学:用生活直觉破解Twist公式的奥秘 刚接触机器人学的同学,一定对Twist(速度旋量)这个概念又爱又恨——它既能精确描述刚体运动,又抽象得让人摸不着头脑。传统教材一上来就抛出ω和v的数学定义&…...

OpenClaw内存优化技巧:Phi-3-vision-128k-instruct在8GB设备上的稳定运行方案

OpenClaw内存优化技巧:Phi-3-vision-128k-instruct在8GB设备上的稳定运行方案 1. 为什么需要内存优化? 去年我在一台老款MacBook Air上第一次尝试部署Phi-3-vision-128k-instruct时,系统几乎立即崩溃。这台仅有8GB内存的设备,在…...

构建具备批判性思维的AI Agent

构建具备批判性思维的AI Agent:从理论到生产级RAG反思循环系统 副标题:拆解GPT-4o、Claude Opus的「逻辑过滤」核心,用LangChain AutoGen Python落地高准确率Agent第一部分:引言与基础 1. 引人注目的标题 (本文已单独…...

三大技术突破:重新定义Android设备标识的完整解决方案

三大技术突破:重新定义Android设备标识的完整解决方案 【免费下载链接】Android_CN_OAID 安卓设备唯一标识解决方案,可替代移动安全联盟(MSA)统一 SDK 闭源方案。包括国内手机厂商的开放匿名标识(OAID)、海…...

2026届毕业生推荐的六大AI写作方案推荐

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 使AIGC检测概率降低的关键之处在于把机器生成时所具有的规律性痕迹予以减少。给出的建议是从…...

如何用CuteTranslation解决Linux屏幕翻译难题:完整技术指南

如何用CuteTranslation解决Linux屏幕翻译难题:完整技术指南 【免费下载链接】CuteTranslation Linux屏幕取词翻译软件 项目地址: https://gitcode.com/gh_mirrors/cu/CuteTranslation CuteTranslation是专为Linux X11环境设计的智能屏幕取词翻译软件&#xf…...

AMPL社区版下载安装全攻略:从注册到运行第一个优化模型(附迅雷加速技巧)

AMPL社区版实战指南:从零开始构建优化模型 第一次接触AMPL时,很多人会被它强大的数学优化能力吸引,却又在安装配置阶段遇到各种"拦路虎"。作为一款专业的数学建模语言,AMPL确实需要一些技巧才能顺利上手。本文将带你避开…...

AI Agent Harness Engineering 开发必备技能栈:编程语言、框架与工具全梳理

AI Agent Harness Engineering 开发必备技能栈:编程语言、框架与工具全梳理 一、引言 (Introduction) 钩子 (The Hook) 你是否见过凌晨三点的硅谷车库咖啡馆?哦,现在的硅谷极客早就不再只盯着屏幕上单调的GAN生成图或微调Transformer的loss曲线了——最近,一杯Espresso旁…...

React Easy State 与 MobX、Redux 对比:哪个更适合你的项目?

React Easy State 与 MobX、Redux 对比:哪个更适合你的项目? 【免费下载链接】react-easy-state Simple React state management. Made with ❤️ and ES6 Proxies. 项目地址: https://gitcode.com/gh_mirrors/re/react-easy-state React 状态管理…...

线性规划实战指南:从基础理论到优化应用

1. 线性规划基础:从菜市场砍价到数学建模 第一次听说线性规划时,我正蹲在菜市场跟大妈讨价还价。大妈说:"西红柿3块一斤,买5斤送半斤",我脑子里瞬间闪过一道光——这不就是典型的线性约束条件吗?…...

Compose Specification快速入门:5个步骤部署你的第一个应用

Compose Specification快速入门:5个步骤部署你的第一个应用 【免费下载链接】compose-spec The Compose specification 项目地址: https://gitcode.com/gh_mirrors/co/compose-spec Compose Specification是一个强大的工具,它允许开发者使用YAML文…...

StableSR故障排除大全:常见问题与解决方案汇总

StableSR故障排除大全:常见问题与解决方案汇总 【免费下载链接】StableSR Exploiting Diffusion Prior for Real-World Image Super-Resolution 项目地址: https://gitcode.com/gh_mirrors/st/StableSR StableSR是一款基于扩散先验的图像超分辨率工具&#x…...

从代码工厂到智能协作者:AI原生研发组织变革的5阶跃迁模型(附SITS2026评估矩阵V2.1)

第一章:从代码工厂到智能协作者:AI原生研发组织变革的5阶跃迁模型(附SITS2026评估矩阵V2.1) 2026奇点智能技术大会(https://ml-summit.org) 传统研发组织正经历一场静默却深刻的范式迁移:代码不再由人单向输出&#…...

DLSSTweaks深度解析:如何通过DLL注入技术解锁NVIDIA DLSS隐藏潜力

DLSSTweaks深度解析:如何通过DLL注入技术解锁NVIDIA DLSS隐藏潜力 【免费下载链接】DLSSTweaks Tweak DLL for NVIDIA DLSS, force DLAA on DLSS-supported titles, tweak scaling ratios & DLSS 3.1 presets, override DLSS versions without overwriting game…...

计算机毕业设计:Python天气大数据爬虫可视化系统 Django框架 线性回归 数据分析 大数据 机器学习 大模型 气象数据(建议收藏)✅

1、项目介绍 技术栈 采用 Python 语言开发,基于 Django 框架搭建 Web 应用程序,使用 MySQL 数据库进行数据存储,前端结合 Bootstrap 框架、CSS、JavaScript 和 HTML 构建界面,运用机器学习中的线性回归算法构建天气预测模型&#…...

OpenCV实战:5分钟搞定视频防抖,让你的Vlog秒变专业级

OpenCV实战:5分钟搞定视频防抖,让你的Vlog秒变专业级 每次用手机拍摄Vlog时,最头疼的就是画面抖动问题。明明构思了完美的镜头,却因为手部微颤导致成片充满业余感。专业级稳定器动辄上千元,而今天我要分享的OpenCV数字…...

深入rust-cross:理解Rust跨编译的术语与架构原理完整指南

深入rust-cross:理解Rust跨编译的术语与架构原理完整指南 【免费下载链接】rust-cross Everything you need to know about cross compiling Rust programs! 项目地址: https://gitcode.com/gh_mirrors/ru/rust-cross Rust跨编译是开发者在不同架构和操作系统…...

STM32光敏传感器实战:从环境检测到智能路灯(附完整代码)

STM32光敏传感器实战:从环境检测到智能路灯(附完整代码) 在物联网和智能硬件快速发展的今天,环境感知技术已成为各类智能设备的基础能力。其中,光线检测作为最常见的环境感知需求之一,广泛应用于智能家居、…...

SQL批量删除旧日志数据_根据创建时间戳进行清理方案

<p>应使用 WHERE created_at > DATE_SUB(NOW(), INTERVAL 1 DAY) 而非 WHERE NOW() - created_at < 86400&#xff0c;以确保索引有效利用。</p>WHERE 条件里用 created_at 而不是 now() 直接减时间直接写 WHERE created_at 看似简洁&#xff0c;但多数 MyS…...

组织熵增 vs AI原生熵减:用香农-组织信息论量化研发效能衰减(SITS2026首次发布行业基准值)

第一章&#xff1a;组织熵增 vs AI原生熵减&#xff1a;用香农-组织信息论量化研发效能衰减&#xff08;SITS2026首次发布行业基准值&#xff09; 2026奇点智能技术大会(https://ml-summit.org) 传统软件研发组织正面临不可逆的“组织熵增”——需求模糊度上升、接口契约漂移…...

ngx-toastr 国际化实现:多语言Toast通知的完整解决方案

ngx-toastr 国际化实现&#xff1a;多语言Toast通知的完整解决方案 【免费下载链接】ngx-toastr &#x1f35e; Angular Toastr 项目地址: https://gitcode.com/gh_mirrors/ng/ngx-toastr ngx-toastr 是一款功能强大的 Angular Toast 通知组件&#xff0c;它允许开发者在…...