1. 在力扣的题目中接触到了树状数组,感觉这个树状数组一开始的时候理解难度还是有点大,但是后面看完相关的例子与资料之后感觉还是可以理解的,树状数组主要是用于某个位置开始的联动修改(结合lowbit函数)与统计某个区间的总和,效率非常高,当发现题目中需要单点修改与区间和查询的时候可以考虑使用树状数组解决
2. 我感觉比较好理解树状数组的的博客:
(1) https://blog.csdn.net/bestsort/article/details/80796531
(2) https://www.cnblogs.com/circlegg/p/7189676.html
(3) https://blog.csdn.net/weixin_30951231/article/details/96959684
其中最主要的是三个函数,lowbit函数、update函数与getsum函数,lowbit函数主要是找到二进制中最低位的1对应的数字,例如110最低位对应的二进制数字是10,十进制为2,update函数可以用来从某个位置开始更新值,getsum函数可以用来统计区间和,感觉树状数组的设计真的很巧妙,下面是关于树状数组的一些代码,我感觉主要是理解清楚lowbit函数那么剩下来的两个函数就比较好理解了,可以结合debug调试来理解
3. 下面的代码可以求解出1-5中的区间和,使用debug可以清楚区间和是怎么样一步步求解出来的
求和操作:(最核心的是lowbit函数)
sum(5) = c[5] + c[4] = 15
sum(4) = c[4] = 10
sum(3) = c[3] + c[2] = 6
sum(2) = c[2] = 3
sum(1) = c[1] = 1
更新操作:是求和操作的逆过程
public class Main {
public static int c[];
public static void main(String[] args) {
c = new int[6];
for (int i = 1; i <= 5; ++i){
update(i, i, 5);
}
System.out.println(getsum(5));
}
public static void update(int x, int y, int n){
for(int i = x; i <= n; i += lowbit(i)) {
c[i] += y;
}
}
public static int getsum(int x) {
int ans = 0;
for (int i = x; i > 0; i -= lowbit(i))
ans += c[i];
return ans;
}
public static int lowbit(int num) {
return num & -num;
}
}