差分陣列(解決區間 a問題)

2021-10-20 11:19:04 字數 2248 閱讀 4772

面試題 16.10. 生存人數

難度中等27

給定 n 個人的出生年份和死亡年份,第i個人的出生年份為birth[i],死亡年份為death[i],實現乙個方法以計算生存人數最多的年份。

你可以假設所有人都出生於 1900 年至 2000 年(含 1900 和 2000 )之間。如果乙個人在某一年的任意時期處於生存狀態,那麼他應該被納入那一年的統計中。例如,生於 1908 年、死於 1909 年的人應當被列入 1908 年和 1909 年的計數。

如果有多個年份生存人數相同且均為最大值,輸出其中最小的年份。

示例:

輸入:birth = 

death =輸出:1901

題解:這裡顯然的想法是構建乙個生存人數的的陣列,儲存不同年份的生存人數,取最大值。儲存的方式首先會想到遍歷birth和death陣列,對每個區間的年份對其進行全加1,這一方法顯然可行,然而由於每個區間都需要對區間內所有年份+1,時間複雜度較高。

一種顯著提高效能的方法是採用差分陣列,對於儲存生存人數的陣列data來說,差分陣列定義為:

進而,可以推導出data[n]  = diff[0] + diff[1] + ... + diff[n],可以發現差分陣列跟字首和相對應。

有了差分陣列後,可以發現,對於data區間 [i , j] 的數值同時+a,差分陣列僅需要在diff[i] + a, diff[j + 1] - a兩步操作即可。

因此通過簡單的遍歷birth和death來維護乙個差分陣列即可代表我們想要的儲存生存人數data陣列。

class solution ;

for (int i = 0; i < birth.size(); ++i)

int res = 0, year = 0, sum = 0;

for (int i = 0; i < 102; ++i)

} return year + 1900;

}};

995. k 連續位的最小翻轉次數

難度困難190

在僅包含01的陣列a中,一次k位翻轉包括選擇乙個長度為k的(連續)子陣列,同時將子陣列中的每個0更改為1,而每個1更改為0

返回所需的k位翻轉的最小次數,以便陣列沒有值為0的元素。如果不可能,返回-1

示例 1:

輸入:a = [0,1,0], k = 1輸出:2解釋:先翻轉 a[0],然後翻轉 a[2]。
示例 2:

輸入:a = [1,1,0], k = 2輸出:-1解釋:無論我們怎樣翻轉大小為 2 的子陣列,我們都不能使陣列變為 [1,1,1]。
示例 3:

輸入:a = [0,0,0,1,0,1,1,0], k = 3輸出:3解釋:翻轉 a[0],a[1],a[2]: a變成 [1,1,1,1,0,1,1,0]

翻轉 a[4],a[5],a[6]: a變成 [1,1,1,1,1,0,0,0]

翻轉 a[5],a[6],a[7]: a變成 [1,1,1,1,1,1,1,1]

1 <= a.length <= 300001 <= k <= a.length

題解:這道題與上題類似,同樣是區間+a的問題,採用差分陣列,對於該題來說,還需要判斷某個點的值在累加的翻轉次數後是否仍需翻轉。

class solution 

}return res;}};

差分陣列概述

在網上講差分陣列的博文很少,也很難找到。一度以為差分陣列是傳播於小眾的神犇技巧所以一直放著沒有去研習。今天做了 bzoj1635後發現各路神犇都用差分陣列,本蒟卻傻傻寫了線段樹。對於序列a 取a i a i 1 為其差分陣列b i 的值,可以發現,a i bj 1 j i 如 對於序列 a b c ...

港口 差分陣列)

傳送門 思路 因為是區間加減,所以考慮差分陣列,題意變為 要求差分陣列d 2 d 3 d n d 2 d 3 dots d n d 2 d 3 d n 全為0.每次區間加或減會使差分陣列乙個加1,乙個減1,因為要用最小次數,所以每次操作最好產生有效貢獻,可知當為正數或負數的差分陣列變為0後,剩下我們...

差分陣列詳解

學習部落格 題目 來先看一道裸題,有n個數。m個操作,每一次操作,將x y區間的所有數增加z 最後有q個詢問,每一次詢問求出x y的區間和。思路 很明顯,直接用字首和無法快速滿足這個操作,所以我們就用到了差分陣列。設a陣列表示原始的陣列 設d i a i a i 1 1設f i f i 1 d i ...