题解 | #未排序数组中累加和为给定值的最长子数组长度#
未排序数组中累加和为给定值的最长子数组长度
http://www.nowcoder.com/practice/704c8388a82e42e58b7f5751ec943a11
描述
- 给定一个无序数组arr, 其中元素可正、可负、可0。给定一个整数k,求arr所有连续子数组中累加和为k的最长子数组长度。
保证至少存在一个合法的子数组。
方法一
思路
- 枚举法,暴力查找;
- 所谓的连续子数组是指对于一个数组arr,从下标i到下标j的一段数据构成的新数组,而为了找出连续子数组中累加和为k的最长子数组,可以遍历arr所有的连续子数组,并检查其是否满足累加和为k的条件,找出其中最长的子数组。
- 枚举连续子数组,对于其实位置下标i只需要从0开始,结束位置j则从下标i+1开始,双重循环遍历即可。
- 在枚举的过程中就可以计算累加和,找出满足条件的最长子数组。
- 代码如下:
import java.util.*; public class Solution { /** * max length of the subarray sum = k * @param arr int整型一维数组 the array * @param k int整型 target * @return int整型 */ public int maxlenEqualK (int[] arr, int k) { if (arr == null || arr.length == 0) { return 0; } // 符合条件的最长子数组长度 int res = 0; int length = arr.length - 1; for(int i = 0;i < length;++i){ int sum = arr[i]; for (int j = i+1;j < arr.length;++j){ // 若和为给定值,则取最大子数组长度 if (sum == k){ int count = j - i; res = Math.max(count,res); } // 继续计算累加和 sum += arr[j]; } if (sum == k){ int count = arr.length - i; res = Math.max(count,res); } } return res; } }
- 时间复杂度:
,双重遍历;
- 空间复杂度:
,常数级空间复杂度。
方法二
思路
- 哈希
- 方法一的时间复杂度为
,有点慢,处理较大的数据比较吃力,所以需要降低算法的时间复杂度。
- 其实在方法一中有很多次重复计算,譬如说,在计算了1~4的连续子数组的累加和后,计算1~5的连续子数组同样计算了一遍1~4的累加和,浪费资源,所以需要考虑将之前计算的数据记录下来,以减少之后累加和计算所耗费的时间。
- 令S(i)表示0~i的累加和,S(j)则表示0~j的累加和,则j+1~i的累加和为S(i)-S(j)。
- 故可以计算S(i),并使用hash数组来存储记录S(i);因为要找出累加和为k的连续子数组,而当前已经知道S(i),那么我只需要查看hash记录中是否存在S(i)-k这么一个数值,若是存在,则找出出现最早的下标j,
,即连续子数组j+1~i满足题目要求,所以我们只需要依据上述操作,找出所有满足条件的连续子数组,并求出其中的连续最长子数组长度即可。
- 代码如下:
import java.util.*; public class Solution { /** * max length of the subarray sum = k * @param arr int整型一维数组 the array * @param k int整型 target * @return int整型 */ public int maxlenEqualK (int[] arr, int k) { if (arr == null || arr.length == 0) { return 0; } Map<Integer, Integer> map = new HashMap<>(); map.put(0, -1); // 最长子数组长度 int res = 0; // 累加和 int sum = 0; for (int i = 0; i < arr.length; i++) { sum += arr[i]; int temp = sum - k; if (map.containsKey(temp)) { res = Math.max(res, i - map.get(temp)); } // 记录累加和 if (!map.containsKey(sum)) { map.put(sum, i); } } return res; } }
- 时间复杂度:
,一层循环,遍历n个数据;
- 空间复杂度:
,使用hash数组存储累加和。