字首和的應用場景是,需要對某個區間[i…j]頻繁查詢累計和,避免每次查詢都遍歷這個區間。
差分陣列的應用場景是,需要對某個區間[i…j]頻繁地加或減某一值,避免每次都遍歷這個區間。
1. 概念
# 一維字首和:
vector nums;
vector sums(nums.size(
) + 1, 0
); // 空間比nums大1,字首和整體右移一位, 這樣計算不需要考慮陣列越界
for(int i =
0; i < nums.size(
); i++)
解決問題:長度為n的序列,m次詢問,每次輸入一對數a,b。輸出從第a個數到第個數的和;
時間複雜度o(n+m)
計算區間和[l,r]
: int sum
= sums[r + 1
] - sums[l]
;# 二維字首和:
vector> nums;
vector> sums(nums.size(
) + 1, vector
(nums[
0].size(
) + 1, 0));
for(int i =
0; i < nums.size(
); i++)
}解決問題:n行m列的整數矩陣,每次查詢給出x1,y1,x2,y2表示乙個子矩陣的左上角座標和右下角座標,每次輸出子矩陣中所有數的和。
計算子矩陣和[x1,y1] -->
[x2, y2]:
int sum
= sums[x2 + 1
][y2 + 1
] - sums[x2 + 1
][y1] - sums[x1]
[y2 + 1
] + sums[x1]
[y1]
;# 差分陣列:
diff[i]
= nums[i] - nums[i - 1];
由diff反推原陣列, 差分陣列的字首和,即為原陣列。
eg, 要對[i,...,j]區間內的元素整體+3,則令diff[i]
+=3, diff[j + 1
] -=
3即可,複雜度o(
1)。
// 和為k的連續子陣列的個數
// 字首和
/* * sums[i] = sums[i - 1] + nums[i];
* k = sums[i] - sums[j];
*/class
solution
mp[sums]++;
// 遍歷至此,字首和為sums的次數又多了一次
}return count;}}
;
// 航班預訂統計:差分陣列
class
solution
answer[0]
= diff[0]
;for
(int i =
1; i < n; i++
)return answer;}}
;
字首和 差分陣列 刷題總結
字首和主要適用的場景是原始陣列不會被修改的情況下,頻繁查詢某個區間的累加和。字首和,核心 就是下面這段 class prefixsum 查詢閉區間 i,j 的累加和 public intquery int i,int j prefix i 就代表著nums 0.i 1 所有元素的累加和,如果我們想求...
差分陣列與字首和
字首和 字首和顧名思義就是前面i個數的總和。假設有乙個序列a,字首和為s。根據概念很容易知到公式 s i displaystyle sum ia j 如何求區間 l,r 的和呢?sum l,r s r s l 1 那如果要對多個不同區間 l,r 進行加減操作呢?然後輸出某個區間 l,r 的區間和,接...
差分 字首和 菜題 刷
貼碼碼,刷題題 include using namespace std define in read int in const int n 1e5 5 int n,a n int main include using namespace std define in read int in const...