算法-和爲K的子數組

算法-和爲K的子數組

1、和爲K的子數組

560. 和爲K的子數組

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

示例 1 :

輸入:nums = [1,1,1], k = 2
輸出: 2 , [1,1] 與 [1,1] 爲兩種不同的情況。
說明 :

數組的長度爲 [1, 20,000]。
數組中元素的範圍是 [-1000, 1000] ,且整數 k 的範圍是 [-1e7, 1e7]。

這個題是字節面試題,也是Leetcode上一道medium級別的題,題目的意圖也比較明顯,就是找和爲K的連續序列個數。但本題中,數字有可能是亂序的,不能再像劍指offer上那樣用數學法做了。

當然,本題存在暴力解法,時間複雜度爲O(N)。主要思想是聲明兩個指針,一個指向連續序列起始位置,另一個指向連續序列的結尾處,我們利用兩層遍歷,就可以解決這個問題了。方法比較簡單,但時間複雜度爲O(N^2),雖然也能通過測試用例,但要幾百毫秒,換成python這樣的語言一定會超時。

    public int subarraySum(int[] nums, int k) {
        int slow=0,quick=0;
        int tempK=k;
        int count=0;
        while(slow<nums.length){
            if(quick==nums.length){
                tempK=k;
                quick=++slow;
            }else if(tempK-nums[quick]==0){
                count++;
                tempK-=nums[quick++];   
            }else{
                tempK-=nums[quick++];   
            }
        }
        return count;
    }

我們可以用哈希表實現另一種解法,還記得leetcode的第一題嗎?two sum問題,存在着一種使用HashMap實現的O(N)解法,本題目思想和它是一致的。

我們用hashmap來保存同一個sum出現的次數,一旦當前sum等於目標和,那麼當前符合條件的數列數量+1,如果包含sum-k,那麼和爲sum-k的m個子序列與當前元素都可以組成連續序列,所以,當前連續子序列個數要加上m。最後,我們要記錄每個和sum的出現次數。

    public int subarraySum(int[] nums, int k) {
        int sum=0,count=0;
        Map<Integer,Integer> map=new HashMap<>();
        for (int i=0;i<nums.length;i++){
            sum+=nums[i];
            if(sum==k){
                count++;
            }
            if(map.containsKey(sum-k)){
                count+=map.get(sum-k);
            }
            if(!map.containsKey(sum)){
                map.put(sum,1);
            }else {
                map.put(sum,map.get(sum)+1);
            }
        }
        return count;
    }

代碼寫的比較清晰,不過多解讀了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章