Compartir tecnología

01. Matriz (en progreso...)

2024-07-12

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

1. Prefijos y técnicas

(1) Suma de prefijo

La técnica de suma de prefijos es adecuada para calcular rápida y frecuentemente la suma de elementos dentro de un rango de índice.

  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) Suma de prefijo + tabla hash

La matriz de suma de prefijos le ayuda a calcular rápidamente la suma de los elementos de una submatriz, pero ¿qué sucede si se le pide que encuentre una submatriz que cumpla las condiciones?Por ejemplo, dejartenumsBuscando armonía entarget submatriz, incluso con la ayuda de prefijos y matrices, todavía tienes que escribir un bucle for anidado.Pero podemos usar una tabla hash para registrar cada prefijo y el índice correspondiente, de modo que podamos calcular rápidamente la suma objetivo comotargetsubconjunto de

  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. };