最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Leetcode Day4 1

2022-04-04 21:35 作者:我喜歡喝一點(diǎn)點(diǎn)  | 我要投稿

朋友喊我先刷每日一題,對我來說有點(diǎn)難,先試試看……


307. 區(qū)域和檢索 - 數(shù)組可修改

給你一個數(shù)組 nums ,請你完成兩類查詢。


其中一類查詢要求 更新 數(shù)組 nums 下標(biāo)對應(yīng)的值

另一類查詢要求返回數(shù)組 nums 中索引 left 和索引 right 之間( 包含 )的nums元素的 和 ,其中 left <= right

實(shí)現(xiàn) NumArray 類:


NumArray(int[] nums) 用整數(shù)數(shù)組 nums 初始化對象

void update(int index, int val) 將 nums[index] 的值 更新 為 val

int sumRange(int left, int right) 返回數(shù)組 nums 中索引 left 和索引 right 之間( 包含 )的nums元素的 和 (即,nums[left] + nums[left + 1], ..., nums[right])


即:

update(idx, delta):將num加到位置idx的數(shù)字上。

prefixSum(idx):求從數(shù)組第一個位置到第idx(含idx)個位置所有數(shù)字的和。

rangeSum(from_idx, to_idx):求從數(shù)組第from_idx個位置到第to_idx個位置的所有數(shù)字的和



這道題其實(shí)就是實(shí)現(xiàn)前綴數(shù)組。

用O(n)的時間來創(chuàng)建前綴數(shù)組,

該數(shù)組中的第i個位置保存原數(shù)組中前i個元素的和,則對于上述每一個操作,我們有:

update(idx, delta):更新操作需要更新cumulative sum數(shù)組中每一個受此更新影響的前綴和,即從idx其到最后一個位置的前綴和。該操作為O(n)時間復(fù)雜度。

prefixSum(idx):直接返回cumulativeSum[idx + 1]即可。該操作為O(1)時間復(fù)雜度。

rangeSum(from_idx, to_idx):直接返回cumulativeSum[to_idx + 1] - cumulativeSum[from_idx]即可。該操作為O(1)操作。


需要的數(shù)據(jù)結(jié)構(gòu):

Binary Indexed Tree?樹狀數(shù)組或二叉索引樹

Binary Indexed Tree事實(shí)上是將根據(jù)數(shù)字的二進(jìn)制表示來對數(shù)組中的元素進(jìn)行邏輯上的分層存儲。

eg:prefixSum(13) = RANGE(1, 8) + RANGE(9, 12) + RANGE(13, 13)

也就是先求2^3個數(shù)之和,再求2^2個數(shù)之和,再求2^0個數(shù)之和。

如何存儲?



①在第一行中,從第一個開始,沒有截斷,因此依次增加2^n個。1增加2^0,到2,2增加2^1,到4,4增加2^2到8,由于8增加2^3超過14個,則第一行結(jié)束。

②在第二行中,因為1,2都已經(jīng)有了,3截斷到3,所以只有3;

5截斷到7,因此5增加2^0,到6,6增加2^1到8超過8,結(jié)束;

9截斷到14,因此9增加2^0,到10,10增加2^1,到12,12增加2^2到16超過14,結(jié)束;

③在第三行中,7截斷到7,結(jié)束。

11截斷到11,結(jié)束。

13截斷到14,13增加2^0到14,結(jié)束。

1.求和

因此:

prefixSum(13) = prefixSum(0b00001101)

= BIT[13] + BIT[12] + BIT[8]

= BIT[0b00001101] + BIT[0b00001100] + BIT[0b00001000]

13->12->8,依次截去末尾的最后一個1

如何求一個二進(jìn)制數(shù)去掉末尾1得到的值?

x = 13 = 0b00001101?

-x = -13 = 0b11110011?

x & (-x) = 0b00000001?

x - (x & (-x)) = 0b00001100


2.更新數(shù)組內(nèi)的值:

每次都加上最后一個1代表的值

x = 5 = 0b00000101

-x = -5 = 0b11111011

x & (-x) = 0b00000001

x + (x & (-x)) = 0b00000110


3.樹狀數(shù)組的建立:

我們需初始化一個全為0的數(shù)組,并對原數(shù)組中的每一個位置對應(yīng)的數(shù)字調(diào)用一次update(i, delta)操作即可。這是一個O(nlogn)的建立過程。


---------------------------------------------------------------------------

以下為題解(參考了大佬的,我確實(shí)不太行orz但是我相信注釋足夠詳細(xì)了,大家應(yīng)該都可以看懂~):

class NumArray:
? ?def lowbit(self,x:int)->int:
? ? ? ?return x&(-x)

? ?def __init__(self, nums: List[int]):
? ? ? ?self.tree=[0]+nums #從1開始標(biāo)下標(biāo)
? ? ? ?for i in range(1,len(self.tree)):
? ? ? ? ? ?j=i+self.lowbit(i)
? ? ? ? ? ?if j<len(self.tree): ?#對所有這個數(shù)出現(xiàn)后需要update的數(shù)進(jìn)行update
? ? ? ? ? ? ? ?self.tree[j] += self.tree[i]

? ?def preSum(self,index:int)-> int:
? ? ? ?#寫一個函數(shù)獲得1到index的和
? ? ? ?i=index+1 #index表示該數(shù)在nums中的位置,由于下標(biāo)右移1,所以用i存放現(xiàn)在tree數(shù)組的位置
? ? ? ?summ=0
? ? ? ?while i:
? ? ? ? ? ?summ += self.tree[i]
? ? ? ? ? ?i-=self.lowbit(i) #求和
? ? ? ?return summ

? ?def update(self, index: int, val: int) -> None:
? ? ? ?pre_vel=self.sumRange(index,index) #pre_vel代表index位置在前綴數(shù)組中的值
? ? ? ?delta=val-pre_vel #該數(shù)字被更新之后,所有前綴組中相關(guān)的數(shù)都應(yīng)該隨之加上或減去相同的值
? ? ? ?i=index+1 #調(diào)用sumRange時,又調(diào)用preSum,這時候的子函數(shù)里面的index是正確對應(yīng)的,但是update函數(shù)的index是對應(yīng)nums數(shù)組的,而不是tree數(shù)組的
? ? ? ?while i<len(self.tree):
? ? ? ? ? ?self.tree[i] +=delta
? ? ? ? ? ?i+=self.lowbit(i)


? ?def sumRange(self, left: int, right: int) -> int:
? ? ? ?return self.preSum(right)-self.preSum(left-1)
? ?#求left到right之間的數(shù)組和,即用right的前綴和減去left的前綴和


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



Leetcode Day4 1的評論 (共 條)

分享到微博請遵守國家法律
冷水江市| 木兰县| 茌平县| 和静县| 登封市| 横山县| 竹溪县| 合阳县| 开阳县| 青川县| 平舆县| 宜城市| 亳州市| 大石桥市| 含山县| 伊金霍洛旗| 麦盖提县| 当涂县| 北海市| 南丹县| 临泉县| 商洛市| 永福县| 闽清县| 弥勒县| 讷河市| 项城市| 塘沽区| 汝城县| 兴城市| 桑植县| 贵港市| 汕尾市| 汤阴县| 巴林右旗| 翁牛特旗| 肥城市| 犍为县| 安塞县| 榕江县| 长海县|