↓快轉到主要內容
  1. LeetCode/

LeetCode 560: Subarray Sum Equals K

·2 分鐘· ·
LeetCode Daily Medium Prefix-Sum
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試: 2025-04-19

  • 總花費時間:15:00.00 (TLE)
  • 2026-10-28 重寫:Wrong Answer → Accepted

解題思路
#

這是一題 prefix sum(前綴和)問題,但由於題目限制 1 <= nums.length <= 2 * 10^4,如果使用暴力解法會很容易遇到 TLE(Time Limit Exceeded)。

一開始我嘗試使用 prefix sum 並搭配雙層迴圈,列舉所有的 (i, j) 來計算所有子陣列的總和。然而因為陣列過大,O(n^2) 的時間複雜度是無法接受的。

後來我從討論區學到一種更好的做法,利用 Hash Map 來記錄 prefix sum 出現的次數。

核心思路如下:

  • 遍歷陣列的同時,計算目前累積的 prefix sum(記為 count)。
  • 每遇到一個元素,就檢查 count - k 是否存在於 Hash Map 中:
    • 如果存在,代表從某個 prefix sum 到當前位置之間的子陣列總和為 k,就可以把 count - k 出現的次數加到結果中。
  • 最後,記得將目前的 count 次數更新進 Hash Map。

這個做法將時間複雜度降為 O(n),可以有效解決原本暴力法會超時的問題。

解法
#

TLE解法
#

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        n = len(nums)

        ps = [0]* (n+1)

        for i in range(n):
            ps[i+1] = nums[i] + ps[i]

        res = 0
        for i in range(n):
            for j in range(i, n):
                if ps[j+1]-ps[i] == k:
                    res+=1

        return res
class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        sub_num = {0:1}

        count = res = 0
        for num in nums:
            count += num
            
            if (count - k) in sub_num:
                res += sub_num[count - k]

            sub_num[count] = sub_num.get(count, 0) + 1

        return res

2026-10 重寫
#

2026-10-28 重寫,錯了一次:

  1. 迴圈裡先查 count[k - num] 再加進前綴和。這是把 Two Sum 的「找補數」套錯了地方:要找的是前綴和等於 curr - k 的位置,不是數值等於 k - num。nums = [2,1,1]、k = 2 回傳 1,答案是 2([2] 和 [1,1])。
  2. 改成先 curr += num,再 res += count[curr - k],最後 count[curr] += 1,就過了。

順序很重要:先更新 curr、再查、最後才把自己放進字典,否則 k = 0 時會把空子陣列也算進去。

收穫
#

一開始我被使用 prefix sum 解題的思維所限制。

但後來我意識到,如果我們的目的是要統計某個特定數值出現的次數,將其儲存到 Hash Map 並在需要時查詢,會是更好的做法。

這樣不僅能簡化邏輯,也能大幅降低時間複雜度。

遇到的問題
#

相關文章

LeetCode 724: Find Pivot Index
·1 分鐘
LeetCode Daily Easy Prefix-Sum
LeetCode 解題紀錄
LeetCode 1534: Count Good Triplets
·2 分鐘
LeetCode Daily Easy Prefix-Sum
LeetCode 解題紀錄
LeetCode 1922: Count Good Numbers
·1 分鐘
LeetCode Daily Medium
LeetCode 解題紀錄
LeetCode 3494: Find the Minimum Amount of Time to Brew Potions
·1 分鐘
LeetCode Medium Simulation Prefix-Sum Array
LeetCode 3494 解題筆記:每瓶藥先往前推出最後一位巫師的完成時間(每個人都要等自己有空),再往回扣出每位巫師的完成時間
LeetCode 3070: Count Submatrices with Top-Left Element and Sum Less Than k
·1 分鐘
LeetCode Medium Array Matrix Prefix-Sum
LeetCode 3070 解題筆記:包含左上角的子矩陣就是二維前綴和 P[i][j],數有幾個 <= k
LeetCode 238: Product of Array Except Self
·1 分鐘
LeetCode Medium Array Prefix-Sum
LeetCode 238 解題筆記:答案是左邊所有數的乘積乘上右邊所有數的乘積,兩次掃描,不用除法