01. 数组篇(进行中......)

 一. 前缀和技巧

(1)前缀和

前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和。 

class NumArray {
public:
    vector<int> preSum; //前缀和数组
    NumArray(vector<int>& nums) {
        //preSum[0] = 0,便于计算累加和
        preSum.resize(nums.size() + 1, 0);
        for(int i = 0; i < nums.size(); i++){
            preSum[i + 1] = preSum[i] + nums[i];
        }
    }
    
    int sumRange(int left, int right) {
        // 查询闭区间 [left, right] 的累加和
        return preSum[right + 1] - preSum[left];
    }
};

(2)前缀和+哈希表

前缀和数组帮你快速计算子数组的元素之和,但如果让你寻找某个符合条件的子数组,怎么办?比方说,让你在 nums 中寻找和为 target 的子数组,就算有前缀和数组的帮助,你也要写个嵌套 for 循环。但我们可以借助哈希表记录每个前缀和对应的索引,这样就能快速计算目标和为 target 的子数组了 

class Solution {
public:
    int findMaxLength(vector<int>& nums) {
        int len = 0;
        vector<int> preSum(nums.size() + 1, 0);

        for(int i = 0; i < nums.size(); i++)
            preSum[i+1] = preSum[i] + (nums[i] == 0 ? -1 : 1);

        // 前缀和到索引的映射,方便快速查找所需的前缀和
        unordered_map<int, int> umap;

        for(int i = 0; i < preSum.size(); i++){
            // 如果这个前缀和还没有对应的索引,说明这个前缀和第一次出现,记录下来
            if(umap.find(preSum[i]) == umap.end()) umap[preSum[i]] = i;
            else len = max(len, i - umap[preSum[i]]);
        }
        return len;
    }
};

class Solution {
public:
    bool checkSubarraySum(vector<int>& nums, int k) {
        vector<int>preSum(nums.size() + 1, 0);

        for(int i = 0; i < nums.size(); i++)
            preSum[i + 1] = preSum[i] + nums[i];

        unordered_map<int, int> umap;

        // 寻找 i, j 使得 (preSum[i] - preSum[j]) % k == 0 且 i - j >= 2
        // (preSum[i] - preSum[j]) % k == 0 其实就是 preSum[i] % k == preSum[j] % k
        for(int i = 0; i < preSum.size(); i++){
            auto it = umap.find(preSum[i] % k);
            if(it == umap.end()) umap[preSum[i] % k] = i;
            else if ((i - it->second) >=2) return true;
        }
        return false;
    }
};

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int ans = 0;
        vector<int> preSum(nums.size() + 1, 0);

        for(int i = 0; i < nums.size(); i++){
            preSum[i + 1] = preSum[i] + nums[i];
        }

        // 寻找 i, j 使得 preSum[i] - preSum[j] == k, i > j
        // nums = [1,2,3], k = 3, preSum = [0,1,3,6]
        unordered_map<int, int> umap;
        for(int i = 0; i < preSum.size(); i++){
            if(umap.find(preSum[i] - k) != umap.end()) ans += umap[preSum[i] - k]; // 该语句必须放在前面
            
            if(umap.find(preSum[i]) == umap.end()) umap[preSum[i]] = 1;
            else umap[preSum[i]]++;
        }
        return ans;

    }
};

  

相关推荐

  1. 数据仓库系列01-规划

    2024-07-12 12:12:02       55 阅读
  2. 复试 || 就业day09(2024.01.04)算法

    2024-07-12 12:12:02       51 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 12:12:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 12:12:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 12:12:02       58 阅读
  4. Python语言-面向对象

    2024-07-12 12:12:02       69 阅读

热门阅读

  1. I18N/L10N 历史 / I18N 指南 / libi18n 模块说明

    2024-07-12 12:12:02       18 阅读
  2. ActiViz中的点放置器vtkPointPlacer

    2024-07-12 12:12:02       21 阅读
  3. MySQL远程登录

    2024-07-12 12:12:02       19 阅读
  4. PostgreSQL 基于时间点恢复

    2024-07-12 12:12:02       19 阅读
  5. 如何理解李彦宏说的“不要卷模型,要卷应用”

    2024-07-12 12:12:02       26 阅读
  6. 解决Spring Boot应用中的内存优化问题

    2024-07-12 12:12:02       18 阅读
  7. nginx 详解

    2024-07-12 12:12:02       26 阅读
  8. [Linux安全运维] Nginx相关

    2024-07-12 12:12:02       20 阅读