Skip to content

Latest commit

 

History

History
81 lines (52 loc) · 2.07 KB

File metadata and controls

81 lines (52 loc) · 2.07 KB

307 Range Sum Query - Mutable

Description

link


Solution

树状数组Binary Indexed Tree,又称Fenwick Tree,这是一种查询和修改复杂度均为O(logn)的数据结构。这个树状数组比较有意思,所有的奇数位置的数字和原数组对应位置的相同,偶数位置是原数组若干位置之和,假如原数组A(a1, a2, a3, a4 ...),和其对应的树状数组C(c1, c2, c3, c4 ...)有如下关系:

self.c[1] = nums[0]

self.c[2] = nums[0] + nums[1]

self.c[3] = nums[2]

self.c[4] = nums[0] + nums[1] + nums[2] + nums[3]

self.c[5] = nums[4]

self.c[6] = nums[4] + nums[5]

self.c[7] = nums[6]

self.c[8] = nums[0] + nums[1] + nums[2] + nums[3] + nums[4] + nums[5] + nums[6] + nums[7]

那么是如何确定某个位置到底是有几个数组成的呢,原来是根据坐标的最低位Low Bit来决定的,所谓的最低位,就是二进制数的最右边的一个1开始,加上后面的0(如果有的话)组成的数字,例如1到8的最低位如下面所示:

坐标 二进制 最低位

1 --- 0001 --- 1

2 --- 0010 --- 2

3 --- 0011 --- 1

x & -x is lowbit function, which will return x's rightmost bit 1, e.g. lowbit(7) = 1, lowbit(20) = 4.


Code

class NumArray:

    def __init__(self, nums):
        self.n = len(nums)
        self.a, self.c = nums, [0] * (self.n + 1)
        for i in range(self.n):
            k = i + 1
            while k <= self.n:
                self.c[k] += nums[i]
                k += (k & -k)

    def update(self, i, val):
        diff, self.a[i] = val - self.a[i], val
        i += 1
        while i <= self.n:
            self.c[i] += diff
            i += (i & -i)

    def sumRange(self, i, j):
        res, j = 0, j + 1
        while j:
            res += self.c[j]
            j -= (j & -j)
        while i:
            res -= self.c[i]
            i -= (i & -i)
        return res


# Your NumArray object will be instantiated and called as such:
# obj = NumArray(nums)
# obj.update(i,val)
# param_2 = obj.sumRange(i,j)