日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数组树/fenwicktree/Binary Indexed Tree

發(fā)布時(shí)間:2025/4/16 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数组树/fenwicktree/Binary Indexed Tree 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在解類似 leetcode 307題區(qū)域和檢索 - 數(shù)組可修改的題時(shí),我們可以使用一種比較小眾的數(shù)據(jù)結(jié)構(gòu),數(shù)組樹。

數(shù)組樹的結(jié)構(gòu)依托于數(shù)組,它的結(jié)構(gòu)看起來類似下面這種:

1,2,3。。。。代表他們?cè)跀?shù)組中的位置,在了解為什么有這種數(shù)據(jù)結(jié)構(gòu)之前,請(qǐng)務(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)?,相對(duì)于原來的0值增加了1,則1,2,4,8的值都變?yōu)?;節(jié)點(diǎn)2的值變?yōu)?,相對(duì)于原來的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開始的。并且更新過程中傳入的是相對(duì)于原來該元素增加的值。

class NumArray {FenwickTree tree;int[] nums;public NumArray(int[] nums) {tree = new FenwickTree(nums.length + 1);this.nums = nums;for(int i = 0; i < nums.length; i++){tree.update(i + 1, nums[i]);}}public void update(int i, int val) {tree.update(i + 1, val - nums[i]);nums[i] = val;}public int sumRange(int i, int j) {return tree.query(j + 1) - tree.query(i);} }class FenwickTree{int[] sums;public FenwickTree(int n){sums = new int[n];}public void update(int i, int delta){while(i < sums.length){sums[i] += delta;i += lowbit(i);}}public int query(int i){int sum = 0;while(i > 0){sum += sums[i];i -= lowbit(i);}return sum;}private int lowbit(int i){return i&-i;} }

總結(jié)

以上是生活随笔為你收集整理的数组树/fenwicktree/Binary Indexed Tree的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。