2020-05-15 LeetCode 560 和爲k的子數組 Java

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

示例1:

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

說明:

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

 題目與之前兩數之和、連續子數組和之類的題目比較像,因爲這裏考察的是連續數組,就聯想到可以分別對數組進行遍歷累加,下標i對應的值記錄的是前i個數組值的和,然後每個子數組和可由累加後的值相減得到(nums[i]-nums[j],i>j),遍歷時間複雜度是o(n2)o(n^2),空間複雜度O(1),效率比較低。

 後邊想到一種改進方案,就是求和後升序排序,然後加入判斷條件,從後往前遍歷的話如果差已經小於k說明更前面的子數組均比k小了,可以省略掉。這樣時間複雜度是o(nlogn)o(n2)o(n logn)-o(n^2),但是因爲沒找到java中能排序且返回索引的方法,所以不了了之。

class Solution {
    public int subarraySum(int[] nums, int k) {
        int ans=0;
        for(int i=0;i<nums.length;i++){
            nums[i]+=nums[i-1];
        }
       // Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            for(int j=nums.length-1;j>=i;j--){
                if(nums[j]-nums[i]==k)  ans++;
               // else if(nums[j]-nums[i]<k) break;
            }
        }
        return ans;
    }
}

 最後想到竟然要查詢爲什麼不用Hashmap呢,遍歷的過程把當前所有遍歷值的和加入Hashmap中,並查詢map中是否含有值n滿足sum+n=k,這樣能快速實現子數組和的查找,時間與空間複雜度均爲O(n)

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

在這裏插入圖片描述

 看了題解之後比較驚豔的是代碼的寫法,關於hashmap的更新問題的那一句定了我四行的if else,不得不說要學習的東西還是很多

mp.put(pre, mp.getOrDefault(pre, 0) + 1);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章