Κοινή χρήση τεχνολογίας

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 υποπίνακας, ακόμη και με τη βοήθεια προθεμάτων και πινάκων, πρέπει να γράψετε έναν ένθετο βρόχο για.Μπορούμε όμως να χρησιμοποιήσουμε έναν πίνακα κατακερματισμού για να καταγράψουμε κάθε πρόθεμα και το αντίστοιχο ευρετήριο, έτσι ώστε να μπορούμε να υπολογίσουμε γρήγορα το άθροισμα στόχο ως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. };