1. 程式人生 > 其它 >【LeetCode】560. 和為K的子陣列

【LeetCode】560. 和為K的子陣列

560. 和為K的子陣列

知識點:陣列;字首和

題目描述

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

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


解法一:暴力法

直接以每個元素為首開始;

class Solution {
    public int subarraySum(int[] nums, int k) {
        int sum = 0;
        int count = 0;
        for(int i = 0; i < nums.length; i++){  //依次以元素開始;
            for(int j = i; j < nums.length; i++){  
                sum += nums[j];
                if(sum == k) count++;
            }
            sum = 0; //一次結束後歸零;
        }
        return count;
    }
}

時間複雜度:O(N^N);

解法二:字首和

字首和是很常見的一種解題思路,其含義就是高中學過的數列的前n項和;

所以如果我們要求哪個子序列和為k的話,就可以轉化為求字首和陣列中哪兩個的值相減等於k。這熟悉嗎?對啊,這不就是兩數之和那個題嗎?還記得怎麼做的嗎?就是用雜湊表存,key和value分別就是數值和其索引下標,為什麼存索引下標,因為那個題讓我們求的就是索引下標。那類比一下,這個題呢,這個題是讓我們幹嘛,是求有幾項和,那我們的value就是對應的前n項和為某個值的有幾個,這樣減出來的子序列就有幾個;

// 字首和沒有優化;
class Solution {
    public int subarraySum(int[] nums, int k) {
        int count = 0;
        int[] premsum = new int[nums.length+1]; //比原陣列長一位,第一位置為0;這樣才能把nums[1]包括;
        for(int i = 0; i < nums.length; i++){ //構建字首和陣列;
            premsum[i+1] = premsum[i] + nums[i];
        } 
        for(int i = 0; i < premsum.length-1; i++){
            for(int j = i+1; j < premsum.length; j++){
                if(premsum[j] - premsum[i] == k) count++;
            }
        }
        return count;
    }
}

時間複雜度:依然是O(N^N);

// 字首和+雜湊表;
class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer,Integer> map = new HashMap<>();
        map.put(0,1);
        int premsum = 0;
        int count = 0;
        for(int i = 0; i < nums.length; i++){
            premsum += nums[i];  //字首和;
            if(map.containsKey(premsum-k)) count += map.get(premsum-k);
            map.put(premsum, map.getOrDefault(premsum, 0)+1);  //字首和為不同值的有幾次;
        }
        return count;
    }
}

時間複雜度:O(N);

體會

字首和是一種很常用的思想,要對觸發它的條件敏感 連續子陣列+和,也就是用在哪一種題型裡;
其次,雜湊表也要敏感,比如在一個題目中有兩數之和,那就要去用雜湊表,可以利用其containsKey函式檢索,從而少一次for迴圈;而雜湊表中value的值就由我們要獲得什麼決定,比如此題是獲得子陣列的個數,那value就是每個和的次數;比如我們要獲得子陣列的大小或者下標,那value就是元素的索引,對症下藥。

相關題目

1. 兩數之和
930. 和相同的二元子陣列
724. 尋找陣列的中心下標
1248. 統計「優美子陣列」
974. 和可被 K 整除的子陣列
523. 連續的子陣列和