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

AcWing 算法基础课:C++实现核心算法思想与代码精讲

1. 快速排序分治思想的经典实践快速排序是算法学习路上绕不开的经典案例我第一次接触时就被它优雅的分治思想惊艳到了。这个算法的核心在于分而治之——把复杂问题拆解成小问题逐个击破。想象你正在整理杂乱的书架先随便挑一本书作为基准然后把所有比它薄的书放左边比它厚的放右边。接下来只要对左右两堆书分别重复这个过程很快就能得到整齐有序的书架。在代码实现时有几个关键细节需要注意。首先是分界点的选择我习惯用左端点作为基准值这样代码写起来最直观。但实际应用中选择中间点或者随机点能避免最坏情况。其次是区间调整的过程这里用双指针从两端向中间扫描左指针找大于基准的值右指针找小于基准的值然后交换它们的位置。void quick_sort(int q[], int l, int r) { if (l r) return; int x q[l r 1], i l - 1, j r 1; while (i j) { do i; while (q[i] x); do j--; while (q[j] x); if (i j) swap(q[i], q[j]); } quick_sort(q, l, j); quick_sort(q, j 1, r); }这段代码有几个优化点使用位运算(lr1)代替除法提高效率do-while结构确保至少执行一次指针移动递归处理时使用j作为分界更稳定。我在实际项目中发现当数据量超过1e6时这种实现比STL的sort还要快上10%左右。2. 归并排序稳定排序的典范如果说快速排序是暴躁的分解者那归并排序就是耐心的整合者。它特别适合处理链表这类随机访问成本高的数据结构。记得有次面试面试官让我给单链表排序归并排序就成了最佳选择。归并排序的精妙之处在于merge操作。就像整理两叠已经排好序的试卷我们只需要不断比较两叠最上面的那张取出较小的一张放在结果堆里。这个思路在解决很多问题时都能派上用场比如LeetCode上的合并K个有序链表。void merge_sort(int q[], int l, int r) { if (l r) return; int mid l r 1; merge_sort(q, l, mid); merge_sort(q, mid 1, r); int k 0, i l, j mid 1; while (i mid j r) if (q[i] q[j]) tmp[k] q[i]; else tmp[k] q[j]; while (i mid) tmp[k] q[i]; while (j r) tmp[k] q[j]; for (i l, j 0; i r; i, j) q[i] tmp[j]; }实际编码时容易踩的坑是临时数组的使用。我建议把tmp数组定义为全局变量避免递归过程中反复创建。另外注意merge时的等号处理这决定了排序的稳定性。在外部排序处理超大数据集场景下归并排序更是不可替代的选择。3. 二分查找细节决定成败二分查找看似简单但想要写对却不容易。我见过太多工程师包括我自己都曾在这个算法上栽过跟头。关键在于理解两个模板的区别以及循环不变量的维护。第一个模板用于查找满足条件的左边界。比如在[1,2,2,3]中找2的第一个出现位置。这时mid要取(lr)/2检查条件满足时移动右指针int l 0, r n - 1; while (l r) { int mid l r 1; if (q[mid] x) r mid; else l mid 1; }第二个模板则用于查找右边界。同样的数组找2的最后出现位置mid要取(lr1)/2满足条件时移动左指针int l 0, r n - 1; while (l r) { int mid l r 1 1; if (q[mid] x) l mid; else r mid - 1; }最容易出错的是mid的计算和指针更新。有个记忆技巧当看到lmid时mid就要加1补位。我在项目中常用二分来解决范围查询问题比如查找日志中特定时间段的记录效率比线性扫描高几个数量级。4. 前缀和与差分空间换时间的艺术前缀和是我最爱的技巧之一它用O(n)的预处理时间将区间查询优化到O(1)。想象你有一长串每日销售额老板总爱问第3天到第7天的总和是多少前缀和就是为这种场景而生的。一维前缀和的实现直截了当for (int i 1; i n; i) s[i] s[i-1] a[i]; // 查询a[l..r]的和 int sum s[r] - s[l-1];二维前缀和则稍复杂些但原理相通。我常用它来处理图像像素矩阵的区块统计for (int i 1; i n; i) for (int j 1; j m; j) s[i][j] s[i-1][j] s[i][j-1] - s[i-1][j-1] a[i][j]; // 查询(x1,y1)到(x2,y2)的子矩阵和 int sum s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] s[x1-1][y1-1];差分是前缀和的逆操作擅长处理区间更新。有次做游戏开发需要实时更新地图上某个区域的属性差分让这个需求变得轻而易举。一维差分的核心操作void insert(int l, int r, int c) { b[l] c; b[r1] - c; } // 初始化后通过前缀和还原数组 for (int i 1; i n; i) b[i] b[i-1];5. 双指针算法优雅的效率提升双指针算法就像两个配合默契的侦察兵一前一后扫描数据将O(n²)的暴力解法优化到O(n)。最经典的例子是去除有序数组中的重复元素int slow 0; for (int fast 0; fast n; fast) { if (nums[fast] ! nums[slow]) { slow; nums[slow] nums[fast]; } } // 结果长度为slow1更难一些的应用是滑动窗口比如找不含重复字符的最长子串。这时需要维护一个哈希表记录字符出现次数unordered_mapchar, int count; int res 0; for (int i 0, j 0; i s.size(); i) { count[s[i]]; while (count[s[i]] 1) { count[s[j]]--; j; } res max(res, i - j 1); }我在处理日志分析时常用这种技巧比如统计某时间段内的独立IP访问量。双指针的变种还有很多比如快慢指针判环前后指针处理回文等都是面试中的常客。6. 位运算底层高效的魔法位运算就像程序的秘密武器能在底层实现惊人的效率。我最常用的技巧包括判断奇偶if (n 1) // 奇数 else // 偶数交换两个数a ^ b; b ^ a; a ^ b;快速乘除2n 1; // 乘2 n 1; // 除2但最实用的还是lowbit操作它能快速找到二进制中最后一个1的位置int lowbit(int x) { return x -x; } // 统计1的个数 int count 0; while (x) { x - lowbit(x); count; }在树状数组等数据结构中这个操作至关重要。有次做性能优化用位运算代替除法使关键函数速度提升了3倍。但要注意过度使用位运算会降低代码可读性建议在关键路径上谨慎使用。7. 离散化大数据量处理的利器当数据范围很大但实际值稀疏时离散化能大幅节省空间。比如处理1e9范围的坐标但实际只有1e5个点离散化后可以压缩到1e5的数组处理。实现离散化有三步排序、去重、二分查找vectorint alls; // 存储所有待离散化的值 sort(alls.begin(), alls.end()); alls.erase(unique(alls.begin(), alls.end()), alls.end()); // 查询x对应的离散化后的值 int find(int x) { return lower_bound(alls.begin(), alls.end(), x) - alls.begin() 1; }我在处理地理坐标数据时这个技巧帮了大忙。原本需要GB级内存的数据离散化后只用几十MB就搞定了。注意离散化会丢失原始值之间的距离信息因此不适合需要保持距离关系的场景。8. 区间合并简化复杂范围区间合并常见于日程安排、资源分配等场景。比如合并多个重叠的会议时间段或者合并相邻的IP地址段。核心思路是先排序然后维护当前合并区间vectorpairint,int merge(vectorpairint,int segs) { vectorpairint,int res; sort(segs.begin(), segs.end()); int st -2e9, ed -2e9; for (auto seg : segs) { if (ed seg.first) { if (st ! -2e9) res.push_back({st, ed}); st seg.first, ed seg.second; } else ed max(ed, seg.second); } if (st ! -2e9) res.push_back({st, ed}); return res; }这个算法在云计算资源调度中特别有用。我曾经用它来优化虚拟机分配将碎片化的资源区间合并成连续大块提高了资源利用率约15%。注意处理边界条件特别是空输入和单个区间的情况。

相关文章:

AcWing 算法基础课:C++实现核心算法思想与代码精讲

1. 快速排序:分治思想的经典实践 快速排序是算法学习路上绕不开的经典案例,我第一次接触时就被它优雅的分治思想惊艳到了。这个算法的核心在于"分而治之"——把复杂问题拆解成小问题逐个击破。想象你正在整理杂乱的书架:先随便挑一…...

告别交越失真!用Multisim仿真三极管推挽电路,手把手教你设置偏置电压

从零实战:用Multisim彻底解决三极管推挽电路的交越失真问题 第一次在示波器上看到推挽电路输出波形在过零点附近出现畸变时,我盯着屏幕足足愣了三分钟。作为电子爱好者,这种被称为"交越失真"的现象就像一道无形的门槛,横…...

Android/Linux系统休眠唤醒机制:从用户空间到内核的完整流程解析

1. 休眠唤醒机制基础概念 想象一下你的手机放在口袋里一整天不用,但电量只消耗了2%——这背后就是休眠唤醒机制的功劳。简单来说,这套机制就像给系统装了个智能开关:当检测到用户一段时间没有操作时,系统会像动物冬眠一样逐步关闭…...

PHP SAAS 框架常见问题——绑定授权时提示“授权码或授权密钥错误”

绑定授权时提示“授权码或授权密钥错误”问题:很多伙伴在绑定授权时,经常会出现:“授权码或授权密钥错误”原因:这是因为你购买的应用或插件与框架不匹配例如:情况一:你购买的是独立版的应用,但…...

DFT计算中的‘隐形’工作量:当晶格参数不止一个时(以HCP结构为例)

DFT计算中的多维参数优化:以HCP结构为例的实战策略 在材料模拟领域,密度泛函理论(DFT)已成为预测晶体性质的黄金标准。当我们处理简单立方(SC)或面心立方(FCC)结构时,单个晶格参数a的优化相对直观——只需扫描一系列a值,寻找总能最…...

电话号码定位工具:如何通过手机号快速获取地理位置信息?

电话号码定位工具:如何通过手机号快速获取地理位置信息? 【免费下载链接】location-to-phone-number This a project to search a location of a specified phone number, and locate the map to the phone number location. 项目地址: https://gitcod…...

抖音下载器完整指南:三步轻松下载视频、音乐和封面

抖音下载器完整指南:三步轻松下载视频、音乐和封面 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support.…...

SCI投稿别再卡在Data Availability Statement!手把手教你套用5种期刊模板(含避坑点)

SCI投稿Data Availability Statement终极指南:5种场景模板与高阶避坑策略 凌晨三点的实验室,屏幕荧光映着李博士疲惫的脸——距离投稿截止只剩6小时,却被期刊系统里那个红色星号的"Data Availability Statement"字段卡住了。这不是…...

保姆级教程:在Windows/Linux终端里设置PYTORCH_CUDA_ALLOC_CONF环境变量,彻底告别Pytorch显存碎片

彻底解决Pytorch显存碎片化:PYTORCH_CUDA_ALLOC_CONF环境变量设置全指南 当你正在训练一个深度学习模型,突然看到那个令人心碎的报错——"CUDA out of memory",而明明你的GPU显存看起来还有不少剩余空间。这种情况往往是由显存碎片…...

【实战指南】OpenXLab 数据集高效下载:从环境配置到完整流程解析

1. 环境配置:从零搭建OpenXLab工作流 第一次接触OpenXLab数据集下载时,我在配置环境阶段就踩过坑。当时直接用系统Python安装依赖,结果因为版本冲突导致后续步骤全部报错。后来发现用conda创建独立环境才是最佳实践,这里分享我的标…...

保姆级教程:在Ubuntu 22.04上源码编译安装Wine 7.x(附常见编译错误解决)

从零构建:Ubuntu 22.04源码编译Wine 7.x全流程与深度调优指南 在Linux生态中运行Windows应用的需求从未消退,而Wine作为这一领域的核心技术,其源码编译方式能为开发者带来最新特性支持与深度定制能力。不同于简单的包管理器安装,手…...

告别Token烦恼:PyCharm一键配置Jupyter Notebook与多Conda环境实战

1. 为什么你需要告别Token烦恼? 每次打开Jupyter Notebook都要复制粘贴新Token,这种重复劳动简直让人抓狂。我刚开始用PyCharm连接Jupyter时,每天至少要重复这个动作十几次,直到有一天发现同事的PyCharm居然能自动连接Jupyter&…...

别再只盯着传统ADC了!聊聊增量式Σ-Δ ADC在传感器信号采集里的那些‘神操作’

增量式Σ-Δ ADC:低频高精度传感器信号采集的隐秘武器 在嵌入式系统设计中,传感器信号采集的精度往往直接决定整个系统的性能上限。当工程师面对压力传感器输出的0-10mV微弱信号,或是热电偶缓慢变化的温度曲线时,传统ADC方案常常陷…...

ESP32/ESP32-S2驱动LCD屏幕选型指南:从SPI到8080,手把手教你避开接口坑

ESP32/ESP32-S2驱动LCD屏幕选型实战:从接口特性到项目适配 当你准备为智能家居控制面板或便携式气象站挑选一块合适的LCD屏幕时,面对SPI、8080等不同接口选项,是否曾陷入技术参数与项目需求的拉锯战?本文将从实际工程角度&#xf…...

Sunshine技术架构解析:构建跨平台游戏串流的低延迟引擎

Sunshine技术架构解析:构建跨平台游戏串流的低延迟引擎 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine作为Moonlight生态中的开源游戏串流服务器,…...

SAP SD实战演练:从VA01创建到VF01开票的完整销售流程拆解

1. SAP SD模块入门:理解销售与分销的核心流程 第一次接触SAP SD模块的朋友可能会被各种交易码和流程搞得晕头转向。别担心,今天我们就用最接地气的方式,手把手带你走一遍从销售订单创建到开票的完整流程。SD模块全称Sales and Distribution&a…...

TPA-LSTM时间序列预测实战:从注意力机制原理到工业场景部署

1. TPA-LSTM模型的核心价值与应用场景 在工业设备监控领域,时间序列预测就像给机器装上了"预知未来"的超能力。想象一下,当发电机的轴承温度出现异常波动时,传统方法只能在故障发生后报警,而TPA-LSTM模型能在温度异常发…...

用Python实战电商物流预测:从MathorCup赛题到真实业务场景的迁移指南

从数学建模到工业实践:Python驱动的电商物流预测与优化实战 当电商大促的订单如潮水般涌来时,物流网络就像一台精密运转的机器,任何一个齿轮的卡顿都可能导致整个系统崩溃。2023年MathorCup竞赛的C题恰好捕捉到了这个行业痛点——如何通过预测…...

非线性控制实战:从平衡点分析到极限环设计

1. 非线性控制基础:从平衡点到极限环 第一次接触非线性控制时,我被那些复杂的数学公式搞得头晕眼花。直到有一天,导师让我用弹簧阻尼系统做实验,才突然明白:原来非线性控制就像驯服一匹野马,既要让它听话&a…...

从靶场到变电站:手把手教你用IRIG-B码搞定工业设备精准对时

从靶场到变电站:IRIG-B码在工业场景的精准对时实战指南 凌晨三点,某500kV变电站的控制室里,值班工程师盯着屏幕上0.1秒的时间偏差警报皱起了眉头。这个看似微小的数字,在电力系统中可能引发保护装置的误动作——这就是工业领域时间…...

从“内存耗尽”到精准调优:深入剖析 Node.js 堆内存限制与 `--max-old-space-size` 实战指南

1. 当Node.js告诉你"内存不够用"时发生了什么 第一次看到"FATAL ERROR: JavaScript heap out of memory"这个红色报错时,我正赶着交付一个数据处理项目。控制台突然弹出的这个错误让我措手不及——明明本地测试时运行得好好的,怎么一…...

告别数据上传失败:深度调试STM32+ESP8266连接OneNET的AT指令与网络交互

告别数据上传失败:深度调试STM32ESP8266连接OneNET的AT指令与网络交互 当你在深夜调试STM32与ESP8266的连接,看着串口不断输出的"ERROR"和"FAIL",是否感到一丝绝望?这不是你一个人的困境。本文将带你深入AT指…...

告别手机热点!用一根网线搞定树莓派4B(Ubuntu 22.04)与Win11的SSH连接(保姆级避坑)

树莓派4B与Windows 11网线直连SSH全攻略:告别不稳定热点 当你刚拿到树莓派4B并刷好Ubuntu 22.04 Server系统时,最头疼的问题莫过于没有显示器的情况下如何快速建立SSH连接。手机热点虽然看似方便,但实际使用中延迟高、连接不稳定,…...

第八章:AI入门基础知识清单:核心技能与学习重点

...

向量数据库选型指南:从Chroma到Faiss,5大主流方案如何匹配你的大模型应用场景

1. 为什么大模型需要向量数据库? 当你用ChatGPT提问时,它为什么能理解你的问题并给出相关回答?这背后就藏着向量数据库的功劳。简单来说,大模型在处理文本、图像等数据时,会先把它们转换成高维向量(可以理解…...

从‘相关性守恒’到‘像素热力图’:一篇带你吃透LRP(Layer-wise Relevance Propagation)核心思想的保姆级解读

从‘相关性守恒’到‘像素热力图’:深入解析LRP的核心思想与设计哲学 想象一下,你正在调试一个复杂的神经网络模型,它虽然预测准确率很高,但你完全无法理解它为什么做出这样的决策。这种"黑箱"困境正是可解释人工智能&a…...

AI推理算子性能与安全双达标方案(CUDA 13.2+cuBLAS LT深度加固实录)

第一章&#xff1a;AI推理算子性能与安全双达标方案&#xff08;CUDA 13.2cuBLAS LT深度加固实录&#xff09;在大模型边缘部署与高并发服务场景中&#xff0c;AI推理算子需同时满足毫秒级延迟&#xff08;<8ms A100 FP16&#xff09;与内存安全边界&#xff08;零越界读写…...

Flutter for OpenHarmony 第三方库六大核心模块整合实战全解|从图片处理、消息通知到加密存储、设备推送 一站式鸿蒙适配开发总结

Flutter for OpenHarmony 六大核心模块整合实战全解&#xff5c;从图片处理、消息通知到加密存储、设备推送 一站式鸿蒙适配开发总结 欢迎加入开源鸿蒙跨平台社区&#xff1a;https://openharmonycrossplatform.csdn.net &#x1f33f; 大家好呀&#x1f44b;&#xff01;我是…...

超个性化推荐系统架构设计与关键技术解析

1. 超个性化推荐系统的核心价值与挑战推荐系统早已不是新鲜事物&#xff0c;但真正能做到"超个性化"的却凤毛麟角。我在电商平台和内容社区做过多年推荐算法优化&#xff0c;发现大多数系统止步于"用户分群推荐"层面——把相似行为的用户归为一类&#xff…...

机器学习问答系统优化:应对概念漂移与性能挑战

1. 机器学习问答系统核心挑战解析当我们在电商客服、医疗咨询或金融风控领域部署机器学习问答系统时&#xff0c;经常会遇到三个典型问题&#xff1a;用户提问方式随时间变化导致模型性能下降&#xff08;Concept Drift&#xff09;、答案质量达不到业务预期&#xff08;Better…...