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

关于算法的一些思考

作为一个acm仔,我又回来写算法文章了,已经快一年没碰算法的我,在最近的简单算法复习中突然有了新的思考。记得在大一大二的时候,都是机械化的为了比赛刷题,背板子。或许不知道从什么时候开始,早就已经没有了最开始的热爱。废话不说,谈谈对最近对算法的一些理解吧。我认为算法本质就是信息复用。

“利用每次运算的额外信息减少重复劳动”,这正是很多高效算法的核心逻辑。无论是二分查找的 “范围收缩”,还是马拉车算法的 “对称复用”,本质上都是通过对 “已有信息” 的最大化利用,避免无效的重复计算,从而实现效率的跃升。我们可以结合具体例子,更细致地拆解这种 “信息复用” 的逻辑:

一、二分查找:用 “比较结果” 切割问题边界,排除无效范围

二分查找的优化逻辑,完美诠释了 “用信息减少重复劳动”。对于一个有序数组,暴力查找需要逐个比较(O (n)),本质是因为每次比较只能确定 “当前元素是否为目标”,没有产生额外信息;而二分查找的每一步,都能通过一次比较得到 “目标所在的范围”,从而直接排除一半元素。

具体来说:

  1. 初始范围是整个数组(left=0,right=n-1),取中点 mid 比较 nums[mid] 与目标值;
  2. 若 nums[mid] > 目标:说明目标只可能在左半段(right=mid-1),右半段可直接排除;
  3. 若 nums[mid] < 目标:说明目标只可能在右半段(left=mid+1),左半段可直接排除;
  4. 重复上述步骤,每次比较都将问题规模缩小一半(从 n 到 n/2,再到 n/4...),最终复杂度降至 O (log n)。

这里的 “额外信息” 是 **“目标与中点的大小关系”**,它直接决定了 “哪些元素不可能是目标”,从而避免了对这部分元素的重复比较。这种 “用信息切割范围” 的思路,在很多算法中都有体现(如快速排序的 partition 操作,用基准值切割数组为 “小于” 和 “大于” 两部分)。

二、马拉车算法(Manacher):用 “回文对称性” 复用已有计算结果

最长回文子串问题中,暴力解法需要枚举所有可能的中心并向两边扩展(O (n²)),但很多情况下,右边的回文子串可以通过左边已计算的结果直接推导 —— 这正是马拉车算法的核心,它利用 “回文的对称性” 存储额外信息,减少重复扩展。

具体来说:

  1. 马拉车算法通过记录 “当前已知的最长回文右边界 R” 和 “对应的中心 C”;
  2. 当处理新位置 i 时,若 i < R(即 i 在当前回文范围内),则 i 关于 C 的对称点 j = 2C - i
  3. 此时,i 处的回文长度至少与 j 处相同(对称特性),无需从头扩展,只需从 “已知的最小长度” 开始继续向外比较;
  4. 若扩展后超过 R,则更新 C 和 R,为后续位置提供新的 “对称信息”。

这里的 “额外信息” 是 **“之前回文的对称范围和长度”**,它让右边的计算不必从零开始,而是基于左边的结果 “站在巨人的肩膀上”,最终将复杂度从 O (n²) 优化到 O (n)。

三、其他算法中的 “信息复用” 逻辑

这种 “用额外信息减少重复劳动” 的思路,几乎贯穿了所有高效算法:

  • 动态规划(DP):通过存储 “子问题的解”(如斐波那契数列的dp[i]),避免对同一子问题的多次计算,用空间换时间;
  • KMP 算法:通过前缀函数next数组记录 “模式串中已匹配的前缀信息”,当匹配失败时,无需从头比较,而是根据next跳转到最近的有效位置,减少无效匹配;
  • 并查集(Union-Find):通过 “路径压缩” 和 “按秩合并” 记录 “节点的父节点关系”,让每次查询和合并操作的复杂度接近 O (1),避免了对整个树的重复遍历;
  • 滑动窗口:用左右指针维护 “当前有效窗口”,通过窗口内元素的增减动态更新结果(如最长无重复子串),避免对窗口外元素的重复检查。

总结:算法优化的核心 ——“让每一步都不白走”

从本质上看,算法的优化过程,就是对 “信息” 的挖掘和利用过程

  • 低效算法的问题在于 “每一步只解决当前问题,不产生可复用的信息”(如暴力遍历);
  • 高效算法的关键在于 “让每一步运算都产生‘对后续步骤有用的信息’”,从而让后续步骤可以 “少走弯路”。

这种思路也适用于工程实践:比如缓存(Cache)的设计,本质是通过存储 “最近访问的数据”(额外信息),减少对底层存储的重复读取;再比如数据库索引,通过存储 “数据的位置映射”(额外信息),避免全表扫描。

理解了这一点,我们在设计或学习算法时,就可以多问自己:“这一步运算能产生什么可复用的信息?如何让后续步骤利用这些信息?”—— 这往往是突破算法瓶颈的关键。

http://www.dtcms.com/a/305251.html

相关文章:

  • 基于springboot的零食商城的设计与实现/零食销售系统的设计与实现
  • 基于Matlab图像处理的静态雨滴去除与质量评估系统
  • JAVA第五学:方法的使用 调试讲解
  • RAG实战指南 Day 26:RAG系统评估指标与方法
  • 2025年06月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • R语言中 read.table 和 read.delim 之间的区别
  • vue中使用wavesurfer.js绘制波形图和频谱图
  • 数学建模算法-day[14]
  • Java中写文件的显示大小实时性
  • 深入理解 boost::lock_guard<boost::mutex>
  • mybatis-plus由mysql改成达梦数据库
  • 【Linux】重生之从零开始学习运维之Mysql事务
  • Python day28
  • 破解企业无公网 IP 难题:可行路径与实现方法?
  • Three.js 渲染优化处理
  • 【C++算法】74.优先级队列_最后一块石头的重量
  • 查找特定的值
  • zama test
  • BGP团体属性
  • Linux部署各类软件
  • 《剑指offer》-算法篇-位运算
  • 【深度学习新浪潮】什么是世界模型?
  • 洛谷 P9779 [HUSTFC 2023] 不定项选择题
  • 记一次导出pdf表单引发的问题
  • Linux救援模式之简介篇
  • 文件相关问题(AI回答)
  • 【从0开始学习Java | 第5篇】封装
  • 85、【OS】【Nuttx】【番外】gcc 关键字:位域(上)
  • 影翎Antigravity将发布全球首款全景无人机,8月开启公测招募
  • Leetcode 08 java