Skip to content

Commit a2c7340

Browse files
authoredOct 3, 2023
feat: add solutions to lc problem: No.2875 (#1740)
No.2875.Minimum Size Subarray in Infinite Array
1 parent 6b87938 commit a2c7340

File tree

7 files changed

+466
-42
lines changed

7 files changed

+466
-42
lines changed
 

‎solution/2800-2899/2875.Minimum Size Subarray in Infinite Array/README.md

+164-2
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,84 @@
5656

5757
<!-- 这里可写通用的实现逻辑 -->
5858

59+
**方法一:前缀和 + 哈希表**
60+
61+
我们先算出数组 $nums$ 的元素总和,记为 $s$。
62+
63+
如果 $target \gt s$,那么我们可以将 $target$ 减去 $\lfloor \frac{target}{s} \rfloor \times s$,这样就可以将 $target$ 减小到 $[0, s)$ 的范围内。那么此时子数组的长度为 $a = \lfloor \frac{target}{s} \rfloor \times n$,其中 $n$ 是数组 $nums$ 的长度。
64+
65+
接下来,我们只需要在数组 $nums$ 中,找出长度最短的且元素和等于 $target$ 的子数组,或者长度最短的且前缀和加上后缀和等于 $target$,即子数组元素和等于 $s - target$ 的子数组,记长度为 $b$。我们可以通过前缀和加哈希表的方法,找出这样的子数组。
66+
67+
如果找到了这样的子数组,那么最终的答案就是 $a + b$。否则,答案就是 $-1$。
68+
69+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。
70+
5971
<!-- tabs:start -->
6072

6173
### **Python3**
6274

6375
<!-- 这里可写当前语言的特殊实现逻辑 -->
6476

6577
```python
66-
78+
class Solution:
79+
def minSizeSubarray(self, nums: List[int], target: int) -> int:
80+
s = sum(nums)
81+
n = len(nums)
82+
a = 0
83+
if target > s:
84+
a = n * (target // s)
85+
target -= target // s * s
86+
if target == s:
87+
return n
88+
pos = {0: -1}
89+
pre = 0
90+
b = inf
91+
for i, x in enumerate(nums):
92+
pre += x
93+
if (t := pre - target) in pos:
94+
b = min(b, i - pos[t])
95+
if (t := pre - (s - target)) in pos:
96+
b = min(b, n - (i - pos[t]))
97+
pos[pre] = i
98+
return -1 if b == inf else a + b
6799
```
68100

69101
### **Java**
70102

71103
<!-- 这里可写当前语言的特殊实现逻辑 -->
72104

105+
```java
106+
class Solution {
107+
public int minSizeSubarray(int[] nums, int target) {
108+
long s = Arrays.stream(nums).sum();
109+
int n = nums.length;
110+
int a = 0;
111+
if (target > s) {
112+
a = n * (target / (int) s);
113+
target -= target / s * s;
114+
}
115+
if (target == s) {
116+
return n;
117+
}
118+
Map<Long, Integer> pos = new HashMap<>();
119+
pos.put(0L, -1);
120+
long pre = 0;
121+
int b = 1 << 30;
122+
for (int i = 0; i < n; ++i) {
123+
pre += nums[i];
124+
if (pos.containsKey(pre - target)) {
125+
b = Math.min(b, i - pos.get(pre - target));
126+
}
127+
if (pos.containsKey(pre - (s - target))) {
128+
b = Math.min(b, n - (i - pos.get(pre - (s - target))));
129+
}
130+
pos.put(pre, i);
131+
}
132+
return b == 1 << 30 ? -1 : a + b;
133+
}
134+
}
135+
```
136+
73137
```java
74138
class Solution {
75139
public int shortestSubarray(int[] nums, int k) {
@@ -122,13 +186,111 @@ class Solution {
122186
### **C++**
123187

124188
```cpp
125-
189+
class Solution {
190+
public:
191+
int minSizeSubarray(vector<int>& nums, int target) {
192+
long long s = accumulate(nums.begin(), nums.end(), 0LL);
193+
int n = nums.size();
194+
int a = 0;
195+
if (target > s) {
196+
a = n * (target / s);
197+
target -= target / s * s;
198+
}
199+
if (target == s) {
200+
return n;
201+
}
202+
unordered_map<int, int> pos{{0, -1}};
203+
long long pre = 0;
204+
int b = 1 << 30;
205+
for (int i = 0; i < n; ++i) {
206+
pre += nums[i];
207+
if (pos.count(pre - target)) {
208+
b = min(b, i - pos[pre - target]);
209+
}
210+
if (pos.count(pre - (s - target))) {
211+
b = min(b, n - (i - pos[pre - (s - target)]));
212+
}
213+
pos[pre] = i;
214+
}
215+
return b == 1 << 30 ? -1 : a + b;
216+
}
217+
};
126218
```
127219
128220
### **Go**
129221
130222
```go
223+
func minSizeSubarray(nums []int, target int) int {
224+
s := 0
225+
for _, x := range nums {
226+
s += x
227+
}
228+
n := len(nums)
229+
a := 0
230+
if target > s {
231+
a = n * (target / s)
232+
target -= target / s * s
233+
}
234+
if target == s {
235+
return n
236+
}
237+
pos := map[int]int{0: -1}
238+
pre := 0
239+
b := 1 << 30
240+
for i, x := range nums {
241+
pre += x
242+
if j, ok := pos[pre-target]; ok {
243+
b = min(b, i-j)
244+
}
245+
if j, ok := pos[pre-(s-target)]; ok {
246+
b = min(b, n-(i-j))
247+
}
248+
pos[pre] = i
249+
}
250+
if b == 1<<30 {
251+
return -1
252+
}
253+
return a + b
254+
}
131255
256+
func min(a, b int) int {
257+
if a < b {
258+
return a
259+
}
260+
return b
261+
}
262+
```
263+
264+
### **TypeScript**
265+
266+
```ts
267+
function minSizeSubarray(nums: number[], target: number): number {
268+
const s = nums.reduce((a, b) => a + b);
269+
const n = nums.length;
270+
let a = 0;
271+
if (target > s) {
272+
a = n * ((target / s) | 0);
273+
target -= ((target / s) | 0) * s;
274+
}
275+
if (target === s) {
276+
return n;
277+
}
278+
const pos: Map<number, number> = new Map();
279+
let pre = 0;
280+
pos.set(0, -1);
281+
let b = Infinity;
282+
for (let i = 0; i < n; ++i) {
283+
pre += nums[i];
284+
if (pos.has(pre - target)) {
285+
b = Math.min(b, i - pos.get(pre - target)!);
286+
}
287+
if (pos.has(pre - (s - target))) {
288+
b = Math.min(b, n - (i - pos.get(pre - (s - target))!));
289+
}
290+
pos.set(pre, i);
291+
}
292+
return b === Infinity ? -1 : a + b;
293+
}
132294
```
133295

134296
### **...**

‎solution/2800-2899/2875.Minimum Size Subarray in Infinite Array/README_EN.md

+164-2
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,80 @@ It can be proven that there is no subarray with sum equal to target = 3.
5151

5252
## Solutions
5353

54+
**Solution 1: Prefix Sum + Hash Table**
55+
56+
First, we calculate the sum of all elements in the array $nums$, denoted as $s$.
57+
58+
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$.
59+
60+
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.
61+
62+
If we find such a subarray, the final answer is $a + b$. Otherwise, the answer is $-1$.
63+
64+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where n is the length of the array $nums$.
65+
5466
<!-- tabs:start -->
5567

5668
### **Python3**
5769

5870
```python
59-
71+
class Solution:
72+
def minSizeSubarray(self, nums: List[int], target: int) -> int:
73+
s = sum(nums)
74+
n = len(nums)
75+
a = 0
76+
if target > s:
77+
a = n * (target // s)
78+
target -= target // s * s
79+
if target == s:
80+
return n
81+
pos = {0: -1}
82+
pre = 0
83+
b = inf
84+
for i, x in enumerate(nums):
85+
pre += x
86+
if (t := pre - target) in pos:
87+
b = min(b, i - pos[t])
88+
if (t := pre - (s - target)) in pos:
89+
b = min(b, n - (i - pos[t]))
90+
pos[pre] = i
91+
return -1 if b == inf else a + b
6092
```
6193

6294
### **Java**
6395

96+
```java
97+
class Solution {
98+
public int minSizeSubarray(int[] nums, int target) {
99+
long s = Arrays.stream(nums).sum();
100+
int n = nums.length;
101+
int a = 0;
102+
if (target > s) {
103+
a = n * (target / (int) s);
104+
target -= target / s * s;
105+
}
106+
if (target == s) {
107+
return n;
108+
}
109+
Map<Long, Integer> pos = new HashMap<>();
110+
pos.put(0L, -1);
111+
long pre = 0;
112+
int b = 1 << 30;
113+
for (int i = 0; i < n; ++i) {
114+
pre += nums[i];
115+
if (pos.containsKey(pre - target)) {
116+
b = Math.min(b, i - pos.get(pre - target));
117+
}
118+
if (pos.containsKey(pre - (s - target))) {
119+
b = Math.min(b, n - (i - pos.get(pre - (s - target))));
120+
}
121+
pos.put(pre, i);
122+
}
123+
return b == 1 << 30 ? -1 : a + b;
124+
}
125+
}
126+
```
127+
64128
```java
65129
class Solution {
66130
public int shortestSubarray(int[] nums, int k) {
@@ -113,13 +177,111 @@ class Solution {
113177
### **C++**
114178

115179
```cpp
116-
180+
class Solution {
181+
public:
182+
int minSizeSubarray(vector<int>& nums, int target) {
183+
long long s = accumulate(nums.begin(), nums.end(), 0LL);
184+
int n = nums.size();
185+
int a = 0;
186+
if (target > s) {
187+
a = n * (target / s);
188+
target -= target / s * s;
189+
}
190+
if (target == s) {
191+
return n;
192+
}
193+
unordered_map<int, int> pos{{0, -1}};
194+
long long pre = 0;
195+
int b = 1 << 30;
196+
for (int i = 0; i < n; ++i) {
197+
pre += nums[i];
198+
if (pos.count(pre - target)) {
199+
b = min(b, i - pos[pre - target]);
200+
}
201+
if (pos.count(pre - (s - target))) {
202+
b = min(b, n - (i - pos[pre - (s - target)]));
203+
}
204+
pos[pre] = i;
205+
}
206+
return b == 1 << 30 ? -1 : a + b;
207+
}
208+
};
117209
```
118210
119211
### **Go**
120212
121213
```go
214+
func minSizeSubarray(nums []int, target int) int {
215+
s := 0
216+
for _, x := range nums {
217+
s += x
218+
}
219+
n := len(nums)
220+
a := 0
221+
if target > s {
222+
a = n * (target / s)
223+
target -= target / s * s
224+
}
225+
if target == s {
226+
return n
227+
}
228+
pos := map[int]int{0: -1}
229+
pre := 0
230+
b := 1 << 30
231+
for i, x := range nums {
232+
pre += x
233+
if j, ok := pos[pre-target]; ok {
234+
b = min(b, i-j)
235+
}
236+
if j, ok := pos[pre-(s-target)]; ok {
237+
b = min(b, n-(i-j))
238+
}
239+
pos[pre] = i
240+
}
241+
if b == 1<<30 {
242+
return -1
243+
}
244+
return a + b
245+
}
122246
247+
func min(a, b int) int {
248+
if a < b {
249+
return a
250+
}
251+
return b
252+
}
253+
```
254+
255+
### **TypeScript**
256+
257+
```ts
258+
function minSizeSubarray(nums: number[], target: number): number {
259+
const s = nums.reduce((a, b) => a + b);
260+
const n = nums.length;
261+
let a = 0;
262+
if (target > s) {
263+
a = n * ((target / s) | 0);
264+
target -= ((target / s) | 0) * s;
265+
}
266+
if (target === s) {
267+
return n;
268+
}
269+
const pos: Map<number, number> = new Map();
270+
let pre = 0;
271+
pos.set(0, -1);
272+
let b = Infinity;
273+
for (let i = 0; i < n; ++i) {
274+
pre += nums[i];
275+
if (pos.has(pre - target)) {
276+
b = Math.min(b, i - pos.get(pre - target)!);
277+
}
278+
if (pos.has(pre - (s - target))) {
279+
b = Math.min(b, n - (i - pos.get(pre - (s - target))!));
280+
}
281+
pos.set(pre, i);
282+
}
283+
return b === Infinity ? -1 : a + b;
284+
}
123285
```
124286

125287
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution {
2+
public:
3+
int minSizeSubarray(vector<int>& nums, int target) {
4+
long long s = accumulate(nums.begin(), nums.end(), 0LL);
5+
int n = nums.size();
6+
int a = 0;
7+
if (target > s) {
8+
a = n * (target / s);
9+
target -= target / s * s;
10+
}
11+
if (target == s) {
12+
return n;
13+
}
14+
unordered_map<int, int> pos{{0, -1}};
15+
long long pre = 0;
16+
int b = 1 << 30;
17+
for (int i = 0; i < n; ++i) {
18+
pre += nums[i];
19+
if (pos.count(pre - target)) {
20+
b = min(b, i - pos[pre - target]);
21+
}
22+
if (pos.count(pre - (s - target))) {
23+
b = min(b, n - (i - pos[pre - (s - target)]));
24+
}
25+
pos[pre] = i;
26+
}
27+
return b == 1 << 30 ? -1 : a + b;
28+
}
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
func minSizeSubarray(nums []int, target int) int {
2+
s := 0
3+
for _, x := range nums {
4+
s += x
5+
}
6+
n := len(nums)
7+
a := 0
8+
if target > s {
9+
a = n * (target / s)
10+
target -= target / s * s
11+
}
12+
if target == s {
13+
return n
14+
}
15+
pos := map[int]int{0: -1}
16+
pre := 0
17+
b := 1 << 30
18+
for i, x := range nums {
19+
pre += x
20+
if j, ok := pos[pre-target]; ok {
21+
b = min(b, i-j)
22+
}
23+
if j, ok := pos[pre-(s-target)]; ok {
24+
b = min(b, n-(i-j))
25+
}
26+
pos[pre] = i
27+
}
28+
if b == 1<<30 {
29+
return -1
30+
}
31+
return a + b
32+
}
33+
34+
func min(a, b int) int {
35+
if a < b {
36+
return a
37+
}
38+
return b
39+
}
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,29 @@
11
class Solution {
2-
public int shortestSubarray(int[] nums, int k) {
3-
int n = nums.length;
4-
int minLength = n * 2 + 1;
5-
int l = 0;
6-
int sum = 0;
7-
8-
for (int r = 0; r < n * 2; r++) {
9-
int start = l % n;
10-
int end = r % n;
11-
sum += nums[end];
12-
13-
while (sum > k && l <= r) {
14-
start = l % n;
15-
sum -= nums[start];
16-
l++;
17-
}
18-
19-
if (sum == k) {
20-
minLength = Math.min(minLength, r - l + 1);
21-
start = l % n;
22-
sum -= nums[start];
23-
l++;
24-
}
25-
}
26-
27-
return minLength == n * 2 + 1 ? -1 : minLength;
28-
}
29-
302
public int minSizeSubarray(int[] nums, int target) {
3+
long s = Arrays.stream(nums).sum();
314
int n = nums.length;
32-
int sum = 0;
33-
34-
for (int num : nums) {
35-
sum += num;
5+
int a = 0;
6+
if (target > s) {
7+
a = n * (target / (int) s);
8+
target -= target / s * s;
9+
}
10+
if (target == s) {
11+
return n;
3612
}
37-
int k = target % sum;
38-
int ans = target / sum * n;
39-
if (k == 0) {
40-
return ans;
13+
Map<Long, Integer> pos = new HashMap<>();
14+
pos.put(0L, -1);
15+
long pre = 0;
16+
int b = 1 << 30;
17+
for (int i = 0; i < n; ++i) {
18+
pre += nums[i];
19+
if (pos.containsKey(pre - target)) {
20+
b = Math.min(b, i - pos.get(pre - target));
21+
}
22+
if (pos.containsKey(pre - (s - target))) {
23+
b = Math.min(b, n - (i - pos.get(pre - (s - target))));
24+
}
25+
pos.put(pre, i);
4126
}
42-
int res = shortestSubarray(nums, k);
43-
return res == -1 ? -1 : ans + res;
27+
return b == 1 << 30 ? -1 : a + b;
4428
}
4529
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution:
2+
def minSizeSubarray(self, nums: List[int], target: int) -> int:
3+
s = sum(nums)
4+
n = len(nums)
5+
a = 0
6+
if target > s:
7+
a = n * (target // s)
8+
target -= target // s * s
9+
if target == s:
10+
return n
11+
pos = {0: -1}
12+
pre = 0
13+
b = inf
14+
for i, x in enumerate(nums):
15+
pre += x
16+
if (t := pre - target) in pos:
17+
b = min(b, i - pos[t])
18+
if (t := pre - (s - target)) in pos:
19+
b = min(b, n - (i - pos[t]))
20+
pos[pre] = i
21+
return -1 if b == inf else a + b
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function minSizeSubarray(nums: number[], target: number): number {
2+
const s = nums.reduce((a, b) => a + b);
3+
const n = nums.length;
4+
let a = 0;
5+
if (target > s) {
6+
a = n * ((target / s) | 0);
7+
target -= ((target / s) | 0) * s;
8+
}
9+
if (target === s) {
10+
return n;
11+
}
12+
const pos: Map<number, number> = new Map();
13+
let pre = 0;
14+
pos.set(0, -1);
15+
let b = Infinity;
16+
for (let i = 0; i < n; ++i) {
17+
pre += nums[i];
18+
if (pos.has(pre - target)) {
19+
b = Math.min(b, i - pos.get(pre - target)!);
20+
}
21+
if (pos.has(pre - (s - target))) {
22+
b = Math.min(b, n - (i - pos.get(pre - (s - target))!));
23+
}
24+
pos.set(pre, i);
25+
}
26+
return b === Infinity ? -1 : a + b;
27+
}

1 commit comments

Comments
 (1)

vercel[bot] commented on Oct 3, 2023

@vercel[bot]

Successfully deployed to the following URLs:

leetcode – ./

leetcode-doocs.vercel.app
leetcode-git-main-doocs.vercel.app
doocs-leetcode.vercel.app

Please sign in to comment.