1. 程式人生 > >LeetCode : 303. 區域和檢索 - 陣列不可變(Range Sum Query - Immutable)解答

LeetCode : 303. 區域和檢索 - 陣列不可變(Range Sum Query - Immutable)解答

303. 區域和檢索 - 陣列不可變

給定一個整數陣列 nums,求出陣列從索引 ij (i ≤ j) 範圍內元素的總和,包含 i, j 兩點。

示例:

給定 nums = [-2, 0, 3, -5, 2, -1],求和函式為 sumRange()

sumRange(0, 2) -> 1
sumRange(2, 5) -> -1
sumRange(0, 5) -> -3

說明:

  1. 你可以假設陣列不可變。
  2. 多次 呼叫 sumRange 方法。

一、思路

  1. 首先,如果只是單純的求 [i, j]
    的和,那就太簡單了。這題主要是考察 多次 呼叫 sumRange 方法,保證不超時。
  2. 所以,你要是直接簡單求和,耗時肯定達不到要求。
  3. 其次,我想到使用一個二維陣列,當求解 [i, j] 和時,直接返回 sums[i][j] 即可。求和過程中,先求解長度為 1 的解,再求解長度為 2, 3, … 的解,我們可以反覆利用已經求解過的區段的和。然而這樣耗時依舊是 O(n2) 的,耗時也沒過關。
  4. 最後,有一個規律其實很重要,即: sum[i, j] = sum[0, j] - sum[0, i - 1]
  5. 有了上述規律,我們只需要一個一維陣列,儲存 [0, n] (0 <= n < nums.length) 的和即可,這樣也只需要遍歷一次陣列即可。

二、解答

/**
 * Copyright © 2018 by afei. All rights reserved.
 * 
 * @author: afei
 * @date: 2018年11月5日
 */

class NumArray {
    
    private int[] sums;

    public NumArray(int[] nums) {
        sums = new int[nums.length];
        if (nums.length == 0) {
            return;
        }
        sums[
0] = nums[0]; for (int i = 1; i < nums.length; i++) { sums[i] += sums[i - 1] + nums[i]; } } public int sumRange(int i, int j) { if (i == 0) { return sums[j]; } else { return sums[j] - sums[i - 1]; } } } /** * Your NumArray object will be instantiated and called as such: * NumArray obj = new NumArray(nums); * int param_1 = obj.sumRange(i,j); */

三、專案地址

https://github.com/afei-cn/LeetCode/tree/master/303.%20Range%20Sum%20Query%20-%20Immutable

四、原題地址

https://leetcode-cn.com/problems/range-sum-query-immutable/description/