[LeetCode] 325. Maximum Size Subarray Sum Equals k

Given an integer array nums and an integer k, return the maximum length of a subarray that sums to k. If there is not one, return 0 instead.

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.

Constraints:

  • 1 <= nums.length <= 2 * 105
  • -104 <= nums[i] <= 104
  • -109 <= k <= 109

和等于 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 }

 

二刷的时候发现直接用hashmap记录unique的前缀和就可以了,不用再用一个额外数组记录前缀和。

时间O(n)

空间O(n)

Java实现

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

 

前缀和prefix sum题目总结

LeetCode 题目总结

posted @ 2020-07-18 05:10  CNoodle  阅读(241)  评论(0编辑  收藏  举报