LeetCode303题:区域和检索——数组不可变

版权声明:本文为博主原创文章,转载请注明出处! https://blog.csdn.net/ASN_forever/article/details/84979828

常规思路:

这道题说白了就是要你写一个函数,这个函数有两个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]);
	}
}

猜你喜欢

转载自blog.csdn.net/ASN_forever/article/details/84979828