数组树/fenwicktree/Binary Indexed Tree
在解類似 leetcode 307題區(qū)域和檢索 - 數(shù)組可修改的題時(shí),我們可以使用一種比較小眾的數(shù)據(jù)結(jié)構(gòu),數(shù)組樹。
數(shù)組樹的結(jié)構(gòu)依托于數(shù)組,它的結(jié)構(gòu)看起來類似下面這種:
1,2,3。。。。代表他們在數(shù)組中的位置,在了解為什么有這種數(shù)據(jù)結(jié)構(gòu)之前,請務(wù)必先看看上面提到的leetcode 307題。
在數(shù)組樹中有兩個(gè)主要的操作函數(shù)更新和查詢。在更新數(shù)組中的某一個(gè)位置的數(shù)值的時(shí)候,其所有祖先節(jié)點(diǎn)全部都要更新,比如節(jié)點(diǎn)1更新,則2,4,8節(jié)點(diǎn)全部都要更新,更新的方式為當(dāng)前節(jié)點(diǎn)的值加上子節(jié)點(diǎn)或自身更新后增加的值,比如現(xiàn)在節(jié)點(diǎn)1的值變?yōu)?,相對于原來的0值增加了1,則1,2,4,8的值都變?yōu)?;節(jié)點(diǎn)2的值變?yōu)?,相對于原來的0值增加了4,則2,4,8的值變?yōu)?。這種更新方式實(shí)際上是要在數(shù)組樹中維護(hù)這樣一個(gè)關(guān)系,節(jié)點(diǎn)值為sum(child.val) + self.val。
如果要更新數(shù)組樹,那么必須找到更新的節(jié)點(diǎn)的所有祖先節(jié)點(diǎn),計(jì)算方法為 i += lowbit(i);lowbit()的意思為數(shù)的二進(jìn)制從最低位往高位計(jì)算,到第一個(gè)為1的位置,這之間的所有的二進(jìn)制構(gòu)成的數(shù),比如1(b0001)的lowbit為(b0001),相加為2(b0010),2的lowbit為(b0010)相加為4(b0100)。lowbit的計(jì)算公式為lowbit(x) = x & (-x);以5為例,x = 5 = b0110 ,-x = ~x + 1 = b1010,lowbit(5) = 0010;
以上就是就是數(shù)組樹的更新過程,如果要查詢數(shù)組樹,也就是獲得前i個(gè)數(shù)組元素的和為多少時(shí),畢竟這才是我們的目的,這時(shí)就需要用到另一種計(jì)算節(jié)點(diǎn)的方式。經(jīng)過上面數(shù)組樹更新方式的描述,我們可以很清楚的知道4存放了1,2,3,4的和,6存放了5,6的和,8存放了所有值的和,如果要計(jì)算前7個(gè)數(shù)的和,可想而知是要將數(shù)組樹中4,6,7節(jié)點(diǎn)值相加。這實(shí)際上也有一個(gè)計(jì)算公式,i -= lowbit(i);它看起來就像下面這樣。
這就是leetcode 307題所需要的數(shù)據(jù)結(jié)構(gòu),現(xiàn)在我們使用這個(gè)數(shù)據(jù)結(jié)構(gòu)將這一題解決。在做題過程中一定要注意fenwicktree的下標(biāo)是從1開始的。并且更新過程中傳入的是相對于原來該元素增加的值。
總結(jié)
以上是生活随笔為你收集整理的数组树/fenwicktree/Binary Indexed Tree的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vscode设置代码编辑时组合键代替方向
- 下一篇: JVM运行时数据区概览