1. 程式人生 > 其它 >劍指 Offer II 010. 和為 k 的子陣列

劍指 Offer II 010. 和為 k 的子陣列

給定一個整數陣列和一個整數k ,請找到該陣列中和為k的連續子陣列的個數。

示例 1 :

輸入:nums = [1,1,1], k = 2
輸出: 2
解釋: 此題 [1,1] 與 [1,1] 為兩種不同的情況
示例 2:

輸入:nums = [1,2,3], k = 3
輸出: 2

提示:

1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107<= k <= 107

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/QTMn0o
題解:

乍一看,以為是滑動視窗的題,直接暴力,但是資料裡面有複數,而滑動視窗要求均為整數

這裡要用字首和+hash map

時間複雜度過高是因為,使用了一個迴圈去求解 sum[i] - sum[j - 1] = k 的結果,這個過程消耗的時間複雜度為 O(n)。對 sum[i] - sum[j - 1] = k 做下變形為 sum[j - 1] = sum[i] - k,所以這個迴圈要找的就是 sum[j - 1] = sum[i] - k 的個數。這個過程使用雜湊表就可以將時間複雜度由 O(n) 降為 O(1),因為當前的 sum[i] 是已知計算得到的,而 sum[j - 1] 也只不過是之前計算得到的 sum 而已,若設定雜湊表的鍵為字首和 sum[i],值為每個和出現的次數,那麼就可以做到優化。

res+=ma[now-k]>0?ma[now-k]:0; //判斷字首差為K 是否存在,存在則加上。不存在加0.
 1 class Solution {
 2 public:
 3     int subarraySum(vector<int>& nums, int k) {
 4         map<int,int> ma;
 5         int n=nums.size(),res=0,now=0;
 6         ma[0]=1;
 7         for(int i=0;i<n;i++)
 8         { 
 9             now+=nums[i];
10 res+=ma[now-k]>0?ma[now-k]:0;//用於找是否存在字首和的差是k的數 11 ma[now]>0?ma[now]++:ma[now]=1; //存字首和 12 } 13 return res; 14 } 15 };