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

常规思路:

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

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值