差分算法(java)
一、差分的核心记录「变化量」而非「具体值」先举个生活例子你就懂了假设你有一本记账本记录每天的零花钱第 1 天5 元第 2 天7 元第 3 天7 元第 4 天10 元如果用「普通记录法」对应原数组就是记[5,7,7,10]如果用「差分记录法」只记当天比前一天多了多少前一天默认 0第 1 天5 - 0 5 元比第 0 天多 5第 2 天7 - 5 2 元比第 1 天多 2第 3 天7 - 7 0 元比第 2 天没多第 4 天10 - 7 3 元比第 3 天多 3最终差分记录的数组差分数组就是[5,2,0,3]。一句话总结差分差分数组d是原数组a的「相邻变化量数组」核心公式下标从 1 开始d[i] a[i] - a[i-1]a[0]默认为 0。反过来知道差分数组也能还原原数组把差分数组从头累加算前缀和就行。比如上面的差分数组[5,2,0,3]第 1 天5累加第 1 个第 2 天527累加前 2 个第 3 天5207累加前 3 个第 4 天520310累加前 4 个刚好还原出原数组这就是差分的「可逆性」。二、差分的真正价值快速改区间差分不是为了记录数据而是为了高效修改区间值—— 这也是竞赛里用它的核心原因。还是用零花钱举例如果想给「第 2 天到第 4 天」每天的零花钱都加 3 元两种做法对比普通做法直接改原数组需要改 3 个位置第 2 天7310第 3 天7310第 4 天10313 → 改 3 次。差分做法只改差分数组的 2 个位置最后还原就行想让「第 2 天开始」都加 3 → 差分数组第 2 位 3d[2] 235想让「第 5 天41停止」加 3 → 差分数组第 5 位 -3但这里只有 4 天不用管改完差分数组是[5,5,0,3]还原后第 1 天5第 2 天5510第 3 天10010第 4 天10313 → 结果一样但只改了 2 次如果区间是「第 2 天到第 10000 天」普通做法要改 9999 次差分还是只改 2 次 —— 这就是效率的天壤之别三、差分改区间的通用规则必记对原数组的区间[l, r]所有数加val只需对差分数组做d[l] val从 l 开始后面都加 vald[r1] - val到 r 结束r1 开始取消加 val。如果 r 是数组最后一位d[r1]可以不管因为超出数组范围了不影响还原总结差分本质是记录「原数组相邻元素的变化量」而非具体值差分的核心优势是修改区间值只需操作 2 个位置时间复杂度从 O (n) 降到 O (1)差分数组能通过「前缀和」还原出原数组是可逆的。简单说差分就是为了「批量改区间」而生的工具竞赛里遇到「给某个区间所有数加 / 减一个值」的题优先想差分准没错
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2414309.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!