[LeetCode] 325. Maximum Size Subarray Sum Equals k

Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't one, return 0 instead.

Note:
The sum of the entire nums array is guaranteed to fit within the 32-bit signed integer range.

Example 1:

Input: nums = [1, -1, 5, -2, 3], k = 3
Output: 4 
Explanation: The subarray [1, -1, 5, -2] sums to 3 and is the longest.

Example 2:

Input: nums = [-2, -1, 2, 1], k = 1
Output: 2 
Explanation: The subarray [-1, 2] sums to 1 and is the longest.

Follow Up:
Can you do it in O(n) time?

和等于 k 的最长子数组长度。题意是给一个数组和一个数字K,请你返回数组中最长的子数组,子数组的和需要等于K。

思路是前缀和prefix sum。跟其他几道前缀和的题类似,借着一个例子跑一下吧,

Input: nums = [1, -1, 5, -2, 3], k = 3
Output: 4 
Explanation: The subarray [1, -1, 5, -2] sums to 3 and is the longest.

首先计算出数组的前缀和,数组变为[1, 0, 5, 3, 6]。接着遍历这个前缀和的数组,用hashmap记录<prefix sum, i> - 每个不同的前缀和他们出现的位置。如果此时发现nums[i] - k在hashmap中,则res = Math.max(res, i - map.get(nums[i] - k))。这个例子里面,K = 3,前缀和跑到3的时候,发现3-3 = 0在hashmap里出现过,此时结算出来的res = 4。当然,之后在遍历到6的时候这里也能结算一次,但是因为这个地方结算的res的长度较短所以并不能更新结果。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public int maxSubArrayLen(int[] nums, int k) {
 3         // corner case
 4         if (nums == null || nums.length == 0) {
 5             return 0;
 6         }
 7 
 8         // normal case
 9         int res = 0;
10         HashMap<Integer, Integer> map = new HashMap<>();
11         map.put(0, -1);
12         for (int i = 1; i < nums.length; i++) {
13             nums[i] += nums[i - 1];
14         }
15         for (int i = 0; i < nums.length; i++) {
16             if (map.containsKey(nums[i] - k)) {
17                 res = Math.max(res, i - map.get(nums[i] - k));
18             }
19             if (!map.containsKey(nums[i])) {
20                 map.put(nums[i], i);
21             }
22         }
23         return res;
24     }
25 }

前缀和prefix sum题目总结

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/13334417.html