一、Problem
Given an array of integers arr and an integer target.
You have to find two non-overlapping sub-arrays of arr each with sum equal target. There can be multiple answers so you have to find an answer where the sum of the lengths of the two sub-arrays is minimum.
Return the minimum sum of the lengths of the two required sub-arrays, or return -1 if you cannot find such two sub-arrays.
Input: arr = [3,2,2,4,3], target = 3
Output: 2
Explanation: Only two sub-arrays have sum = 3 ([3] and [3]). The sum of their lengths is 2.
Constraints:
1 <= arr.length <= 10^5
1 <= arr[i] <= 1000
1 <= target <= 10^8
二、Solution
方法一:前綴和
- 用 map 記錄前綴和的每一項出現的位置
- Q:如果找和爲 tar 的子數組呢?
A:如果pre[i] - tar
在 map 的 keySet 中出現過,如果出現位置爲 ,且當前位置爲 ,則表明數組中存在一段長爲 的且和爲 tar 的子數組。 - Q:如何判斷兩個和爲 tar 的子數組是否重疊?
A:第二長的子數組的左端點大於大於第一小的子數組的右端點。證明:第一短的子數組一定是第一個找到,第二長的子數組一定是第二個找到。
class Solution {
public int minSumOfLengths(int[] a, int tar) {
int n = a.length, INF = 0x3f3f3f3f, pre[] = new int[n+1];
Map<Integer, Integer> mp = new HashMap<>();
mp.put(0, 0);
for (int i = 1; i <= n; i++) {
pre[i] = pre[i-1] + a[i-1];
mp.put(pre[i], i);
}
int fir = INF, sec = INF, minR = 0;
for (int r = 1; r <= n; r++) {
int d = pre[r] - tar;
if (mp.containsKey(d)) {
int l = mp.get(d), len = Math.abs(r - l);
if (len < fir) {
minR = r;
sec = fir;
fir = len;
} else if (len < sec && l >= minR)
sec = len;
}
}
return fir != INF && sec != INF ? fir+sec : -1;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,