技術共有

01. アレイ (進行中...)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. 接頭辞とテクニック

(1) プレフィックス合計

プレフィックス合計手法は、インデックス範囲内の要素の合計を迅速かつ頻繁に計算するのに適しています。

  1. class NumArray {
  2. public:
  3. vector<int> preSum; //前缀和数组
  4. NumArray(vector<int>& nums) {
  5. //preSum[0] = 0,便于计算累加和
  6. preSum.resize(nums.size() + 1, 0);
  7. for(int i = 0; i < nums.size(); i++){
  8. preSum[i + 1] = preSum[i] + nums[i];
  9. }
  10. }
  11. int sumRange(int left, int right) {
  12. // 查询闭区间 [left, right] 的累加和
  13. return preSum[right + 1] - preSum[left];
  14. }
  15. };

(2) プレフィックス合計+ハッシュテーブル

プレフィックス合計配列は、部分配列の要素の合計をすばやく計算するのに役立ちますが、条件を満たす部分配列を見つけるように要求された場合はどうすればよいでしょうか?たとえば、nums調和を求めてtargetサブ配列では、プレフィックスと配列を使用したとしても、ネストされた for ループを記述する必要があります。ただし、ハッシュ テーブルを使用して各プレフィックスと対応するインデックスを記録できるため、ターゲットの合計を次のようにすばやく計算できます。targetの部分配列

  1. class Solution {
  2. public:
  3. int findMaxLength(vector<int>& nums) {
  4. int len = 0;
  5. vector<int> preSum(nums.size() + 1, 0);
  6. for(int i = 0; i < nums.size(); i++)
  7. preSum[i+1] = preSum[i] + (nums[i] == 0 ? -1 : 1);
  8. // 前缀和到索引的映射,方便快速查找所需的前缀和
  9. unordered_map<int, int> umap;
  10. for(int i = 0; i < preSum.size(); i++){
  11. // 如果这个前缀和还没有对应的索引,说明这个前缀和第一次出现,记录下来
  12. if(umap.find(preSum[i]) == umap.end()) umap[preSum[i]] = i;
  13. else len = max(len, i - umap[preSum[i]]);
  14. }
  15. return len;
  16. }
  17. };

  1. class Solution {
  2. public:
  3. bool checkSubarraySum(vector<int>& nums, int k) {
  4. vector<int>preSum(nums.size() + 1, 0);
  5. for(int i = 0; i < nums.size(); i++)
  6. preSum[i + 1] = preSum[i] + nums[i];
  7. unordered_map<int, int> umap;
  8. // 寻找 i, j 使得 (preSum[i] - preSum[j]) % k == 0 且 i - j >= 2
  9. // (preSum[i] - preSum[j]) % k == 0 其实就是 preSum[i] % k == preSum[j] % k
  10. for(int i = 0; i < preSum.size(); i++){
  11. auto it = umap.find(preSum[i] % k);
  12. if(it == umap.end()) umap[preSum[i] % k] = i;
  13. else if ((i - it->second) >=2) return true;
  14. }
  15. return false;
  16. }
  17. };

  1. class Solution {
  2. public:
  3. int subarraySum(vector<int>& nums, int k) {
  4. int ans = 0;
  5. vector<int> preSum(nums.size() + 1, 0);
  6. for(int i = 0; i < nums.size(); i++){
  7. preSum[i + 1] = preSum[i] + nums[i];
  8. }
  9. // 寻找 i, j 使得 preSum[i] - preSum[j] == k, i > j
  10. // nums = [1,2,3], k = 3, preSum = [0,1,3,6]
  11. unordered_map<int, int> umap;
  12. for(int i = 0; i < preSum.size(); i++){
  13. if(umap.find(preSum[i] - k) != umap.end()) ans += umap[preSum[i] - k]; // 该语句必须放在前面
  14. if(umap.find(preSum[i]) == umap.end()) umap[preSum[i]] = 1;
  15. else umap[preSum[i]]++;
  16. }
  17. return ans;
  18. }
  19. };