LeetCode303題:區域和檢索——陣列不可變
阿新 • • 發佈:2018-12-26
常規思路:
這道題說白了就是要你寫一個函式,這個函式有兩個int型的形參i和j,分別表示陣列的兩個下標,然後需要返回這兩個下標及其之間的所有數的和。如果只考慮單次呼叫的需求的話,直接從i到j累加就完了。但說明中提到,函式會被多次呼叫。那麼如果每次呼叫都從i到j累加一遍的話,之前累加的結果就浪費了,相同的i和j每次都會做重複的累加,效率就會很低了。因此需要換一種思路。
非常規解法:初始化陣列和 ( 時間O(1),空間O(1) )
思路:在初始化陣列nums的時候,從下標1開始,將每個位置的數替換成其之前所有數和它累加後的和。這樣初始化後,要求i到j之間所有數的和的時候,只需要用nums[j] - nums[i-1]即可。為什麼時間複雜度是O(1)呢?這有個前提,就是呼叫sumRange()的次數很大很大,遠大於陣列長度。這樣在初始化時的N次計算就可以當成常數了。如果只調用幾次sumRange()的話,那麼其複雜度就是O(N)了,跟每次都計算累加的複雜度一樣。
class NumArray {
private static int[] sum;
public NumArray(int[] nums) {
if (nums.length > 1) {
for (int i = 1; i < nums.length; i++) {
nums[i] += nums[i - 1];
}
}
sum = nums;
}
public int sumRange(int i, int j) {
return sum[j] - (i == 0 ? 0 : sum[i - 1]);
}
}