初級樹狀數組 leetcode 練習題

2021-02-21 天空的代碼世界
分享幾個簡單的樹狀數組練習題。一、背景

之前分享了《樹狀數組模板》和《離散化模板》,今天來看幾道練習題。

二、區域和檢索 - 數組可修改

題意:給一個數組,有兩個操作。 

1)求區間[l,r]的和。
2)修改下標 i 的值為v。

思路:題意是單點更新,求區間和。
赤裸裸的樹狀數組模板題,直接套用即可。

代碼:

https://github.com/tiankonguse/leetcode-solutions/blob/master/problemset-new/003/00307-range-sum-query-mutable/range-sum-query-mutable.cc

三、計算右側小於當前元素的個數

題意:給一個數組,求每個位置右側比自己小的元素個數。

思路:如果不看數據範圍的話,裸套樹狀數組模板即可。
具體細節是從後到前遍歷,先通過前綴和求出小於自己的元素個數,然後把自己再加入到樹狀數組中。

這道題的元素值很大,所以需要使用離散化模板進行重新標號。

代碼:

https://github.com/tiankonguse/leetcode-solutions/blob/master/problemset-new/003/00315-count-of-smaller-numbers-after-self/count-of-smaller-numbers-after-self.cc

四、翻轉對

題意:給一個數組,求每個元素左側大於兩倍當前值的元素個數。
使用數學公式就是,求 i<j 且num[i] > num[j]*2 的個數。

思路:與上一題類似,只是大小關係只是變成了兩倍。
求大於當前值的個數,其實就是求後綴和了。

所以只需要使用 Upper 算法找到第一個大於兩倍值的下標,然後求後綴和即可。

代碼:

https://github.com/tiankonguse/leetcode-solutions/blob/master/problemset-new/004/00493-reverse-pairs/reverse-pairs.cc

五、區間和的個數

題意:給一個數組,問區間和在[lower, upper]範圍內的區間個數。

思路:暴力是O(n^2)的複雜度,我們需要想出一個更快的算法來。

我們可以思考這樣一個情況。
從左到右掃描數組的時候,假設當前位置是j。
如果我們能快速找到以j為後綴的滿足要求的區間,那就可以快速找到答案了。

再進一步假設。
假設我們已經有所有以j為後綴的區間和了,儲存在樹狀數組裡。

sum[1 , j]

...

sum[j-2, j]

sum[j-1, j]

sum[j , j]

那就可以log(n)的複雜度來查詢後綴和在區間[l, r]的個數了。

那如何由第j個元素的後綴和轉化為第j+1個元素的後綴和呢?

j的所有後綴和加上nums[j+1],就幾乎都是j+1的所有後綴和了。

sum[1 , j] + nums[j+1]

...

sum[j-2, j] + nums[j+1]

sum[j-1, j] + nums[j+1]

sum[j , j] + nums[j+1]

nums[j+1]

上面的話聚合在一起就是求 j的所有後綴和 加上 num[j+1] 後,值在範圍 [l, r]內的個數。

那反過來,根據小學二年級學的一個性質,兩邊同時減去一個數字,答案不變。
所以 區間[l, r] 和 j的所有後綴和可以都減去nums[j+1]。
問題就轉化為了所有 j的後綴和滿足區間 [l-nums[j+1], r-nums[j+1]]的個數。

到這裡,不知道你是否還明白在說什麼。
簡單的說,我們通過修改區間[l, r]就可以將j+1的後綴和問題轉化為j的後綴和問題。

這裡唯一需要注意的就是,最後一個元素nums[j+1]不是j的後綴和,所以沒辦法直接減去nums[j+1]。
所以這裡需要通過原始的[l,r]與 j的區間進行偏移修正,將nums[j+1]轉化為j的後綴和形式。

修正的值其實也很容易計算。
通過j到j+1的關係,可以發現修正一次的偏移量是nums[j+1]。
那麼j到j+2修正偏移量就nums[j+1] + nums[j+2]了。

提取規律,第k個值需要修正的偏移量就是前綴和sum[1, k]了。

代碼:

https://github.com/tiankonguse/leetcode-solutions/blob/master/problemset-new/003/00327-count-of-range-sum/count-of-range-sum.cc

六、最後

這四道樹狀數組的題都很有特徵。

第一道是裸套模板。
第二道是稍微變通一下來套模版。
第三道則存在非離散化的數據,需要使用Upper或者Lower來查找第一個滿足情況的下標。
第四道題則屬於最難的,需要反向修改查詢的區間,這種思路可以學習一下,是個不錯的思路。

加油,算法人。

《完》

-EOF-

題圖:來自朋友圈。

上篇文章: 必備算法模版之大數據離散化

推薦:必備算法模版之樹狀數組

長按二維碼,一起成長學習

▲ 長按關注,天天成長

覺得有幫助可以點擊好看與轉發,謝謝!

相關焦點

  • LeetCode刷題第三周【數組(簡單)】
    參考資料[1]Leetcode網站: https://leetcode-cn.com/[2]以上文字描述均來自 LeetCode數組模塊: https://leetcode-cn.com/tag/array/[3]刷題請點擊或見附錄:1539.
  • AK leetcode 流浪計劃 - 數組反轉
    一、簡介二、基本操作步驟三、作用四、反轉模板交換元素的方法模板總結1 反轉數組區間2 反轉數組區間中的特定元素五、牛刀小試練習1 反轉字符串題目大意題目解析AC代碼練習2 反轉鍊表題目大意題目解析思路AC代碼練習3 反轉字符串中的元音字母題目大意題目解析AC代碼練習4 反轉字符串中的單詞 III題目大意題目解析AC代碼六、代碼模板七、總結八
  • [LeetCode] 912. Sort an Array 數組排序
    Output: [1,2,3,5]Example 2:Input: [5,1,1,2,0,0]Output: [0,0,1,1,2,5]Note:1<=A.length<=10000-50000<=A[i]<=50000這道題讓我們給數組排序
  • ​LeetCode刷題實戰152:乘積最大子數組
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 乘積最大子數組,我們先來看題面:https://leetcode-cn.com/problems/maximum-product-subarray/Given an integer array nums, find the contiguous subarray within an array (containing
  • 樹狀數組,看這一篇就夠了
    也就是說,所謂樹狀數組,或稱Binary Indexed Tree, Fenwick Tree,是一種用於高效處理對一個存儲數字的列表進行更新及求前綴和的數據結構。Binary ranges圖中第一行為原數組,第二到第四行為依次按層填坑的過程。我們需要從左到右,從上到下依次將相應的值填入對應的位置中。最後一行中即為最終所形成的樹狀數組。
  • [LeetCode] 918. Maximum Sum Circular Subarray 環形子數組的最大和
    >Example 5:Input: [-2,-3,-1]Output: -1 Explanation: Subarray [-1] has maximum sum -1Note:-30000<=A[i]<=300001<=A.length<=30000這道題讓求環形子數組的最大和
  • LeetCode 熱題 HOT 100(03,尋找兩個正序數組的中位數)
    LeetCode 熱題 HOT 100(03,尋找兩個正序數組的中位數)不夠優秀,發量尚多,千錘百鍊,方可成佛。算法的重要性不言而喻,無論你是研究者,還是最近比較火熱的IT 打工人,都理應需要一定的算法能力,這也是面試的必備環節,算法功底的展示往往能讓面試官眼前一亮,這也是在大多數競爭者中脫穎而出的重要影響因素。
  • ​LeetCode刷題實戰108:將有序數組轉換為二叉搜索樹
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 將有序數組轉換為二叉搜索樹,我們先來看題面:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/Given an array where elements are sorted in ascending order
  • ​LeetCode刷題實戰81:搜索旋轉排序數組 II
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做 搜索旋轉排序數組 II,我們先來看題面:https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/Suppose an array sorted in ascending order is rotated at some pivot
  • [洛穀日報第22期]可以代替線段樹的樹狀數組?
    樹狀數組進階(1)*前置知識:樹狀數組,如果沒有學過請右轉這篇文章:傳送門,前綴和,差分。*本文代碼均未經編譯,如有錯誤請指出。*前排cqy,826755370,喜歡EXO,bigbang,BTS,ikon,nine percent,本命世勳。
  • leetcode刷題指南之PatchingArray
    給定一個已排序的數組。問: 最少需要往數組中添加多少個數才能使得1 ~ n的數都能由數組中若干數的和得到?
  • 六十四、開始刷Leetcode之旅(Python版本)
    這個是中文的網址:https://leetcode-cn.com/problemset/all/下圖就是我的國際版本,其實我主要在國際版混日子,刷了100多題,其實我很菜的。這是它的官網,https://leetcode.com。
  • ​LeetCode刷題實戰33:搜索旋轉排序數組
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做搜索旋轉排序數組,我們先來看題面:https://leetcode-cn.com/problems/search-in-rotated-sorted-array/You are given an integer array nums sorted in ascending order, and an integer
  • leetcode 刷500道題,筆試/面試穩嗎?
    一、先說說筆試題在刷 leetcode 的時候,你會發現,每道題的題意都很短,你只需要花十幾秒的時間,就知道這道題是要你幹嘛了,並且每道題所用道的算法思想都很明確,動態規劃、遞歸、二分查找等,你可能很快就知道該用哪種方法,只是你不懂如何把代碼寫出來而已。
  • 【每日一題】leetcode刷題指南之Longest Consecutive Sequence
    給你一個未排序的數組,要在O(n)的時間複雜度內求出最長的由數組中元素組成的連續序列的長度。
  • Leetcode weekly contest三月小結
    Time Needed to Inform All Employeeshttps://leetcode.com/problems/time-needed-to-inform-all-employees/題目的大意是一個公司裡的組織結構呈樹狀(除了一個老大以外,每一個員工都有且只有一個manager,並且不會出現環),然後不同manager通知到他們的employees
  • ​LeetCode刷題實戰34:在排序數組中查找元素的第一個和最後一個位置
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做在排序數組中查找元素的第一個和最後一個位置,我們先來看題面:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-arrayGiven an array of integers nums sorted
  • leetcode刷題指南之findtheduplicatenumber
    不能改動原始數組除了原始數組,只能另外開闢O(1)的空間算法複雜度一定要小於O(n^2)重複的那個數可能重複不止一次初看這題可能有很多種方式,但是幾個限制條件一加,很多算法就不可行了。比如不能排序,因為不能改動數組;用Hash保存每個數字出現個數也不行,因為只能另外開闢O(1)的空間而直接兩重循環比較則不能滿足複雜度小於O(n^2)的要求;另外可能會有人用所有數的總和-(1+n) * n/2找出重複的數,但是這個方法也只能適用於重複次數只有1的情況。
  • leetcode每日一題:49.字母異位詞分組
    leetcode每日一題:49.字母異位詞分組:https://leetcode-cn.com/problems/group-anagrams/一起刷題吧一、題意分析 輸入:由字符串組成的列表(數組)輸出:將由同樣的字母和字母個數組成的不同序列放在一個列表裡,然後整體做為一個列表輸出難度
  • leetcode上的幾個區間題
    然後有人問我有沒有題來練習,我去 leetcode 上找了一些,發現有很多題供大家練習。這裡我再介紹一下 map 怎麼維護區間,然後簡單介紹一下題目,大家可以去練習一下。二、基礎知識map 內部是使用紅黑樹實現的,所以 map 的 key 是有序的。