|
…
|
||
|---|---|---|
| .. | ||
| README.md | ||
| README_EN.md | ||
| Solution.cpp | ||
| Solution.go | ||
| Solution.java | ||
| Solution.py | ||
| Solution.ts | ||
README_EN.md
| comments | difficulty | edit_url | rating | source | tags | ||||
|---|---|---|---|---|---|---|---|---|---|
| true | Medium | https://github.com/doocs/leetcode/edit/main/solution/2800-2899/2875.Minimum%20Size%20Subarray%20in%20Infinite%20Array/README_EN.md | 1913 | Weekly Contest 365 Q3 |
|
2875. Minimum Size Subarray in Infinite Array
Description
You are given a 0-indexed array nums and an integer target.
A 0-indexed array infinite_nums is generated by infinitely appending the elements of nums to itself.
Return the length of the shortest subarray of the array infinite_nums with a sum equal to target. If there is no such subarray return -1.
Example 1:
Input: nums = [1,2,3], target = 5 Output: 2 Explanation: In this example infinite_nums = [1,2,3,1,2,3,1,2,...]. The subarray in the range [1,2], has the sum equal to target = 5 and length = 2. It can be proven that 2 is the shortest length of a subarray with sum equal to target = 5.
Example 2:
Input: nums = [1,1,1,2,3], target = 4 Output: 2 Explanation: In this example infinite_nums = [1,1,1,2,3,1,1,1,2,3,1,1,...]. The subarray in the range [4,5], has the sum equal to target = 4 and length = 2. It can be proven that 2 is the shortest length of a subarray with sum equal to target = 4.
Example 3:
Input: nums = [2,4,6,8], target = 3 Output: -1 Explanation: In this example infinite_nums = [2,4,6,8,2,4,6,8,...]. It can be proven that there is no subarray with sum equal to target = 3.
Constraints:
1 <= nums.length <= 1051 <= nums[i] <= 1051 <= target <= 109
Solutions
Solution 1: Prefix Sum + Hash Table
First, we calculate the sum of all elements in the array nums, denoted as s.
If target \gt s, we can reduce target to the range [0, s) by subtracting \lfloor \frac{target}{s} \rfloor \times s from it. Then, the length of the subarray is a = \lfloor \frac{target}{s} \rfloor \times n, where n is the length of the array nums.
Next, we need to find the shortest subarray in nums whose sum equals target, or the shortest subarray whose prefix sum plus suffix sum equals s - target. We can use prefix sum and a hash table to find such subarrays.
If we find such a subarray, the final answer is a + b. Otherwise, the answer is -1.
The time complexity is O(n), and the space complexity is O(n), where n is the length of the array nums.
Python3
class Solution:
def minSizeSubarray(self, nums: List[int], target: int) -> int:
s = sum(nums)
n = len(nums)
a = 0
if target > s:
a = n * (target // s)
target -= target // s * s
if target == s:
return n
pos = {0: -1}
pre = 0
b = inf
for i, x in enumerate(nums):
pre += x
if (t := pre - target) in pos:
b = min(b, i - pos[t])
if (t := pre - (s - target)) in pos:
b = min(b, n - (i - pos[t]))
pos[pre] = i
return -1 if b == inf else a + b
Java
class Solution {
public int minSizeSubarray(int[] nums, int target) {
long s = Arrays.stream(nums).sum();
int n = nums.length;
int a = 0;
if (target > s) {
a = n * (target / (int) s);
target -= target / s * s;
}
if (target == s) {
return n;
}
Map<Long, Integer> pos = new HashMap<>();
pos.put(0L, -1);
long pre = 0;
int b = 1 << 30;
for (int i = 0; i < n; ++i) {
pre += nums[i];
if (pos.containsKey(pre - target)) {
b = Math.min(b, i - pos.get(pre - target));
}
if (pos.containsKey(pre - (s - target))) {
b = Math.min(b, n - (i - pos.get(pre - (s - target))));
}
pos.put(pre, i);
}
return b == 1 << 30 ? -1 : a + b;
}
}
C++
class Solution {
public:
int minSizeSubarray(vector<int>& nums, int target) {
long long s = accumulate(nums.begin(), nums.end(), 0LL);
int n = nums.size();
int a = 0;
if (target > s) {
a = n * (target / s);
target -= target / s * s;
}
if (target == s) {
return n;
}
unordered_map<int, int> pos{{0, -1}};
long long pre = 0;
int b = 1 << 30;
for (int i = 0; i < n; ++i) {
pre += nums[i];
if (pos.count(pre - target)) {
b = min(b, i - pos[pre - target]);
}
if (pos.count(pre - (s - target))) {
b = min(b, n - (i - pos[pre - (s - target)]));
}
pos[pre] = i;
}
return b == 1 << 30 ? -1 : a + b;
}
};
Go
func minSizeSubarray(nums []int, target int) int {
s := 0
for _, x := range nums {
s += x
}
n := len(nums)
a := 0
if target > s {
a = n * (target / s)
target -= target / s * s
}
if target == s {
return n
}
pos := map[int]int{0: -1}
pre := 0
b := 1 << 30
for i, x := range nums {
pre += x
if j, ok := pos[pre-target]; ok {
b = min(b, i-j)
}
if j, ok := pos[pre-(s-target)]; ok {
b = min(b, n-(i-j))
}
pos[pre] = i
}
if b == 1<<30 {
return -1
}
return a + b
}
TypeScript
function minSizeSubarray(nums: number[], target: number): number {
const s = nums.reduce((a, b) => a + b);
const n = nums.length;
let a = 0;
if (target > s) {
a = n * ((target / s) | 0);
target -= ((target / s) | 0) * s;
}
if (target === s) {
return n;
}
const pos: Map<number, number> = new Map();
let pre = 0;
pos.set(0, -1);
let b = Infinity;
for (let i = 0; i < n; ++i) {
pre += nums[i];
if (pos.has(pre - target)) {
b = Math.min(b, i - pos.get(pre - target)!);
}
if (pos.has(pre - (s - target))) {
b = Math.min(b, n - (i - pos.get(pre - (s - target))!));
}
pos.set(pre, i);
}
return b === Infinity ? -1 : a + b;
}