lintcode 138. 子数组之和

问题描述

给定一个整数数组,找到和为零的子数组。你的代码应该返回满足要求的子数组的起始位置和结束位置

样例

给出 [-3, 1, 2, -3, 4],返回[0, 2] 或者 [1, 3]

问题分析:

这个问题比较好想的算法的时间复杂度是O(n^2),这不是我们希望看到的。

要解决这个问题我觉得需要明白两点:

1.一个子数组的和为零,我们假设这个子数组是{ a[i], a[i+1], ..., a[j] },也就是a[i] + a[i+1] +...+ a[j] = 0,起始和结束位置其实就是i和j。那么 a[0] + a[1] +...+ a[i-1] + a[i] + a[i+1] +...+ a[j]a[0] + a[1] +...+ a[i-1] 。把这个式子转换下,假如这个数组的前 i 项的和与前j项的和相等,那么i项到j项之间的数组的元素的和肯定是零。i,j就是需要的结果。

所以这个问题就转换成了求数组前n项和的问题

2.假如前 i 项的和为零,那么0 和 i 即为所求结果

我提供一种O(n)的解法,希望对大家有所启发

public List subarraySum(int[] nums) {
        // write your code here
        ArrayList list = new ArrayList<>();
		int[] sumArrays = new int[nums.length];
		sumArrays[0] = nums[0]; 
		for (int i = 1; i < nums.length; i++) {
			sumArrays[i] = sumArrays[i-1] + nums[i]; 
		}
		HashMap indexsMap = new HashMap<>();
		for (int i = 0; i < sumArrays.length; i++) {
		    if (sumArrays[i] == 0) {
				list.add(0);
				list.add(i);
				return list;
			}
			if (indexsMap.containsKey(sumArrays[i])) {
				list.add(indexsMap.get(sumArrays[i])+1);
				list.add(i);
				return list;
			}
			indexsMap.put(sumArrays[i], i);
		}
		return list;
    }





你可能感兴趣的:(lintcode)