181. 差分陣列學習
阿新 • • 發佈:2021-08-31
1.查分陣列
1.首先名字看起來很高大上其實呢就是前一項減後一項, 不用怕 舉個例子: list1 = [2, 5, 4, 9, 7, 10, 0] list1 = [0, 2, 5, 4, 9, 7, 10, 0] # 最前面補一個零(因為第一項沒有前一個元素) diff_list = [] for i in range(1, len(list1)): diff_list.append(list1[i] - list1[i-1]) # 前一項減去後一項 print(diff_list) # 結果就是這個樣子, 他能幹嘛呢? 發現沒有如果給diff_list計算字首和剛好就是原陣列 diff_list = [2, 3, -1, 5, -2, 3, -10] 2.計算字首和(可能你不相信我說字首和就是他的原陣列沒關係,算一遍) size = len(diff_list) list2 = [0 for _ in range(size +1)] for i in range(1, size + 1): # 這裡是為了計算字首和陣列 list2[i] = list2[i-1] + diff_list[i-1] print(list2) [0, 2, 5, 4, 9, 7, 10, 0] 你看看他想不想list1也就是原陣列 這個時候你明白了差分陣列的其中一個作用了把?計算字首和還原陣列 3.產品聽需求了,我們需要給 1. [1, 4]的數值全部加上3 2. 上面條件的基礎上[3, 5] 減去5 是不是感覺很簡單? 遍歷一遍加上去就可以了,但是如果如果數量級比較大1e5你1000ms可以過去麼? 很不幸我在力扣裡面超時了. 這時候就需要利用差分陣列的性質了: 將原始陣列中元素同時加上或者減掉某個數,那麼他們的差分陣列其實是不會變化的 沒事不懂咋就舉例子: list1 = [0, 2, 5, 4, 9, 7, 10, 0] 原陣列 diff_list = [2, 3, -1, 5, -2, 3, -10] 差分陣列 [1, 4]的數值全部加上3 如果我們給差分陣列1索引位置元素+3, 4+1=5所以位置-3會造成什麼? diff_list = [2, 3+3, -1, 5, -2, 3-3, -10] # 說話你們不信, 直接看程式碼, 結果[0, 2, 8, 7, 12, 10, 10, 0], 看到了什麼[1,4]+3了, 其他資料沒影響是不是很完美.(0是我們加的輔助數字不需要管) diff_list = [2, 3+3, -1, 5, -2, 3-3, -10] size = len(diff_list) list2 = [0 for _ in range(size +1)] for i in range(1, size + 1): # 這裡是為了計算字首和陣列 list2[i] = list2[i-1] + diff_list[i-1] print(list2) # [0, 2, 8, 7, 12, 10, 10, 0] 上面條件的基礎上[3, 5] 減去5 # 經過上面我相信你已經明白了,如果需要修改[x,y]位置元素大小隻需要給x位置+對應數字, y+1位置-對應陣列即可(相信減法你可以理解),進行第二個條件 diff_list = [2, 3+3, -1, 5-5, -2, 3-3, -10+5] size = len(diff_list) list2 = [0 for _ in range(size +1)] for i in range(1, size + 1): # 這裡是為了計算字首和陣列 list2[i] = list2[i-1] + diff_list[i-1] print(list2) # [0, 2, 8, 7, 12, 10, 10, 0] [0, 2, 8, 7, 12, 10, 10, 0] # 條件1結果 [0, 2, 8, 7, 7, 5, 5, 0] # 條件2結果 # 防止你們不相信, 我暴力的修改也給出來, 如下 list1 = [2, 5, 4, 9, 7, 10, 0] size = len(list1) for i in range(size): if 1 <= i <= 4: list1[i] += 3 if 3 <= i <= 5: list1[i] -= 5 print(list1) # [2, 8, 7, 7, 5, 5, 0] 4.總結3寫成程式碼diff_list差分陣列 [x, y]位置加上同樣大小的數m diff[x] += m diff[y+1] -= 1 # y+1需要小於陣列長度n, len(diff_list) 注意 只能是區間元素同時增加或減少相同的數的情況才能用 5.實踐開始,
1.題目1: HDU-1556 Color the Ball
說實話第一次遇到查分陣列相關問這個氣球搞得我很懵逼, 但是看了大佬的程式碼一下在就明白了? 我把這題根據力扣的題目改了一下:(還是返回氣球總共修改了幾次) 其中n表示氣球數量, balls陣列放置每次塗改顏色的區間(前後都包含)給你看個例子就好了 例1: n = 3 balls = [[1, 1], [2,3], [3,3]] 結果 [1, 1, 1] 例2: n = 3 balls = [[1, 1], [1,2], [1,3]] 結果 [3, 2, 1] # 這個結果其實就是最後的差分陣列,他記錄了每個位置對應的氣球修改的次數 程式碼如下: def func(balls, n): a = [0 for _ in range(n+1)] # 結果陣列 b = [0 for _ in range(n+1)] # 差分陣列 for i in range(len(balls)): x, y = balls[i] b[x] += 1 # 1其實就是每次修改一遍 if y < n: b[y+1] -= 1 for i in range(1, n+1): a[i] = a[i-1] + b[i] # 字首和 return a[1:]
1.題目二: 1109. 航班預訂統計
這個題很題目一很類似, 上面統計修改次數, 這個題目統計座位數目. 只不過給區間加上了權重,也就是座位數 class Solution(object): def corpFlightBookings(self, bookings, n): """ https://blog.csdn.net/qq_44786250/article/details/100056975 參考這個學習查分陣列 航班編號 1 2 3 4 5 預訂記錄 1 : 10 10 預訂記錄 2 : 20 20 預訂記錄 3 : 25 25 25 25 總座位數: 10 55 45 25 25 :type bookings: List[List[int]] :type n: int :rtype: List[int] """ a = [0 for _ in range(n+1)] b = [0 for _ in range(n+1)] for i in range(len(bookings)): x, y, w = bookings[i] b[x] += w # 同樣的程式碼加上權重就好了 if y < n: b[y+1] -= w for i in range(1, n+1): a[i] = a[i-1] + b[i] return a[1:]