天天看點

[LeetCode] Continuous Subarray Sum 連續的子數組之和

Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer.

Example 1:

Example 2:

Note:

The length of the array won't exceed 10,000.

You may assume the sum of all the numbers is in the range of a signed 32-bit integer.

這道題給了我們一個數組和一個數字k,讓我們求是否存在這樣的一個連續的子數組,該子數組的數組之和可以整除k。遇到除法問題,我們肯定不能忘了除數為0的情況等處理。還有就是我們如何能快速的周遊所有的子數組,并且求和,我們肯定不能完全的暴力破解,這樣OJ肯定不答應。我們需要适當的優化,如果是刷題老司機的話,遇到這種求子數組或者子矩陣之和的題,應該不難想到要建立累加和數組或者累加和矩陣來做。沒錯,這道題也得這麼做,我們要周遊所有的子數組,然後利用累加和來快速求和。在得到每個子數組之和時,我們先和k比較,如果相同直接傳回true,否則再判斷,若k不為0,且sum能整除k,同樣傳回true,最後周遊結束傳回false,參見代碼如下:

解法一:

下面這種方法用了些技巧,那就是,若數字a和b分别除以數字c,若得到的餘數相同,那麼(a-b)必定能夠整除c。這裡就不證明了,部落客也不會證明。明白了這條定理,那麼我們用一個集合set來儲存所有出現過的餘數,如果目前的累加和除以k得到的餘數在set中已經存在了,那麼說明之前必定有一段子數組和可以整除k。需要注意的是k為0的情況,由于無法取餘,我們就把目前累加和放入set中。還有就是題目要求子數組至少需要兩個數字,那麼我們需要一個變量pre來記錄之前的和,我們每次存入set中的是pre,而不是目前的累積和,參見代碼如下:

解法二:

既然set可以做,一般來說用哈希表也可以做,這裡我們建立餘數和目前位置之間的映射,由于有了位置資訊,我們就不需要pre變量了,之前用儲存的坐标和目前位置i比較判斷就可以了,參見代碼如下:

解法三:

繼續閱讀