国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

leetcode307. Range Sum Query - Mutable

Lemon_95 / 915人閱讀

摘要:題目要求可以先參考數(shù)組不發(fā)生變動時的題目。最后的葉節(jié)點為當(dāng)前數(shù)組的值,非葉結(jié)點則記錄了子數(shù)組的范圍以及該子數(shù)組中所有元素的和。它是一個非常輕量級的數(shù)據(jù)結(jié)構(gòu),而且?guī)缀蹙褪菫檫@種題目量身打造。

題目要求

</>復(fù)制代碼

  1. Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.
  2. The update(i, val) function modifies nums by updating the element at index i to val.
  3. Example:
  4. Given nums = [1, 3, 5]
  5. sumRange(0, 2) -> 9
  6. update(1, 2)
  7. sumRange(0, 2) -> 8
  8. Note:
  9. The array is only modifiable by the update function.
  10. You may assume the number of calls to update and sumRange function is distributed evenly.

可以先參考數(shù)組不發(fā)生變動時的題目。

這里的難度在于數(shù)組可以在中間出現(xiàn)變動,那么面對大容量數(shù)組的時候如何選擇一個合適的數(shù)據(jù)結(jié)構(gòu)及很重要。

思路一:map緩存

最開始我們有兩種直觀的想法,一種是在插入時同時更新后面所有的和,這意味著O(n)的插入復(fù)雜度和O(1)的讀取復(fù)雜度。我決定選擇第二種方式,也就是采用類似日志的形式記錄下每一次的變更。這樣當(dāng)我們讀取的時候,再遍歷日志,將相關(guān)的變更結(jié)果添加到當(dāng)前的數(shù)值上。缺點是,變更很多以及數(shù)組很龐大時,效率依然很差。

這個方法超時了。

</>復(fù)制代碼

  1. private int[] sum;
  2. private int[] nums;
  3. private Map log;
  4. public NumArray(int[] nums) {
  5. this.nums = nums;
  6. sum = new int[nums.length];
  7. for(int i = 0 ; i();
  8. }
  9. public void update(int i, int val) {
  10. log.put(i, val - nums[i]);
  11. }
  12. public int sumRange(int i, int j) {
  13. int origin = 0;
  14. if(i==0) origin = sum[j];
  15. else origin = sum[j] - sum[i-1];
  16. for(Integer key : log.keySet()){
  17. if(key>=i && key <= j){
  18. origin += log.get(key);
  19. }
  20. }
  21. return origin;
  22. }
思路二:Segment Tree

我們將一個數(shù)組轉(zhuǎn)化為一棵樹,其中當(dāng)前的數(shù)組被均勻的分割并且分別用左子數(shù)組和右子數(shù)組構(gòu)建左子樹和右子樹。最后的葉節(jié)點為當(dāng)前數(shù)組的值,非葉結(jié)點則記錄了子數(shù)組的范圍以及該子數(shù)組中所有元素的和。

舉個例子說明一下:
假設(shè)當(dāng)前的數(shù)組為[1,2,5],則構(gòu)成的Segment Tree為:

</>復(fù)制代碼

  1. 8
  2. /
  3. 3 5
  4. /
  5. 1 2

這里先將[1,2,5]分割為[1,2][5]兩個子數(shù)組,然后分別構(gòu)造子樹。最后的樹如上所示。

</>復(fù)制代碼

  1. class SegmentTreeNode{
  2. int start;
  3. int end;
  4. SegmentTreeNode left;
  5. SegmentTreeNode right;
  6. int sum;
  7. public SegmentTreeNode(int start, int end){
  8. this.start = start;
  9. this.end = end;
  10. }
  11. }
  12. private SegmentTreeNode buildSegmentTree(int[] nums, int start, int end){
  13. if(start > end) return null;
  14. SegmentTreeNode cur = new SegmentTreeNode(start, end);
  15. if(start == end) cur.sum = nums[start];
  16. else{
  17. int mid = (start + end) / 2;
  18. cur.left = buildSegmentTree(nums, start, mid);
  19. cur.right = buildSegmentTree(nums, mid+1, end);
  20. cur.sum = cur.left.sum + cur.right.sum;
  21. }
  22. return cur;
  23. }
  24. private SegmentTreeNode root;
  25. public NumArray(int[] nums) {
  26. this.root = buildSegmentTree(nums, 0, nums.length-1);
  27. }
  28. public void update(int i, int val) {
  29. update(root, i, val);
  30. }
  31. private void update(SegmentTreeNode root, int position, int val){
  32. if(root.start == root.end){
  33. root.sum = val;
  34. }else{
  35. int mid = (root.start + root.end) / 2;
  36. if(position <= mid){
  37. update(root.left, position, val);
  38. }else{
  39. update(root.right, position, val);
  40. }
  41. root.sum = root.left.sum + root.right.sum;
  42. }
  43. }
  44. public int sumRange(int i, int j) {
  45. return sumRange(root, i, j);
  46. }
  47. public int sumRange(SegmentTreeNode root, int i, int j){
  48. if(root.start==i && root.end==j){
  49. return root.sum;
  50. }
  51. int mid = (root.start + root.end )/2;
  52. if(j<=mid){
  53. return sumRange(root.left, i, j);
  54. }else if(i>mid){
  55. return sumRange(root.right, i, j);
  56. }else{
  57. return sumRange(root.left, i, mid) + sumRange(root.right, mid+1, j);
  58. }
  59. }

要想了解更多關(guān)于Segment Tree,請參考這篇文章。

思路三:Binary Indexed Tree

網(wǎng)上有非常多的關(guān)于二進(jìn)制索引數(shù)樹的教程。它是一個非常輕量級的數(shù)據(jù)結(jié)構(gòu),而且?guī)缀蹙褪菫檫@種題目量身打造。可以先從這篇文章和這篇文章了解一下。

</>復(fù)制代碼

  1. class NumArray {
  2. int[] nums;
  3. int[] BIT;
  4. int n;
  5. public NumArray(int[] nums) {
  6. this.nums = nums;
  7. n = nums.length;
  8. BIT = new int[n + 1];
  9. for (int i = 0; i < n; i++)
  10. init(i, nums[i]);
  11. }
  12. //每次更新當(dāng)前節(jié)點的同時更新父節(jié)點
  13. public void init(int i, int val) {
  14. i++;
  15. while (i <= n) {
  16. BIT[i] += val;
  17. i += (i & -i);
  18. }
  19. }
  20. //更新當(dāng)前節(jié)點,同時將改變傳遞給父節(jié)點
  21. void update(int i, int val) {
  22. int diff = val - nums[i];
  23. nums[i] = val;
  24. init(i, diff);
  25. }
  26. //
  27. public int getSum(int i) {
  28. int sum = 0;
  29. i++;
  30. while (i > 0) {
  31. sum += BIT[i];
  32. i -= (i & -i);
  33. }
  34. return sum;
  35. }
  36. public int sumRange(int i, int j) {
  37. return getSum(j) - getSum(i - 1);
  38. }
  39. }


想要了解更多開發(fā)技術(shù),面試教程以及互聯(lián)網(wǎng)公司內(nèi)推,歡迎關(guān)注我的微信公眾號!將會不定期的發(fā)放福利哦~

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/68694.html

相關(guān)文章

  • Range Sum Query

    摘要:表現(xiàn)在二進(jìn)制上的規(guī)律每次加上最末尾的求末尾的就拿這個數(shù)和它的補(bǔ)碼于。還有要求不是,要轉(zhuǎn)換一下,和之前那道的思路差不多。這里用一個的表示從到的和。 Range Sum Query - Immutable Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), i...

    zhongmeizhi 評論0 收藏0
  • leetcode303-304 Range Sum Query Immutable

    摘要:假設(shè)有一個整數(shù)數(shù)組,計算下標(biāo)從到包含和的數(shù)字的和。求和的請求將會在同一個整數(shù)數(shù)組上多次請求。這一題思路很簡單,因為。而利用動態(tài)規(guī)劃則很容易知道。這里將原先的一維數(shù)組替換成二維數(shù)組。要求計算一個矩形內(nèi)的所有元素的值。 Range Sum Query Immutable Given an integer array nums, find the sum of the elements be...

    Worktile 評論0 收藏0
  • [LeetCode] 304. Range Sum Query 2D - Immutable

    Problem Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2). https://leetcode.com/static/i...s...

    chinafgj 評論0 收藏0
  • [LeetCode] Range Sum Query Immutable

    Problem Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. Example Given nums = [-2, 0, 3, -5, 2, -1] sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRan...

    LiuZh 評論0 收藏0
  • 運用樹狀數(shù)組解決動態(tài)數(shù)組求和

    摘要:對于一組一維數(shù)組解決前項和,如果使用的方法需要的時間來找到前項數(shù)字的和,但是可以用的時間來更新對應(yīng)數(shù)字的值但是仍然需要的時間來更新牽扯到相應(yīng)數(shù)字?jǐn)?shù)組的和,相反可以使用樹狀數(shù)組來降低運行時間求數(shù)組內(nèi)一段數(shù)組的和,但同樣我們增加了更新樹狀數(shù)組內(nèi) 對于一組一維數(shù)組解決前n項和,如果使用linear scan的方法, 需要O(n)的時間來找到前n項數(shù)字的和,但是可以用O(1)的時間來更新對應(yīng)數(shù)...

    Barrior 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<