Skip to content

Commit 7e974e9

Browse files
committed
feat: update solutions to lc problem: No.0862
No.0862.Shortest Subarray with Sum at Least K
1 parent db5683c commit 7e974e9

File tree

6 files changed

+88
-73
lines changed

6 files changed

+88
-73
lines changed

solution/0800-0899/0862.Shortest Subarray with Sum at Least K/README.md

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,25 @@
5050

5151
<!-- 这里可写通用的实现逻辑 -->
5252

53-
**方法一:单调队列**
53+
**方法一:前缀和 + 单调队列**
54+
55+
题目要求找到一个最短的子数组,使得子数组的和大于等于 $k$。不难想到,可以使用前缀和快速计算子数组的和。
56+
57+
我们用一个长度为 $n+1$ 的数组 $s[i]$ 表示数组 `nums` 前 $i$ 个元素的和。另外,我们需要维护一个严格单调递增的队列 $q$,队列中存储的是前缀和数组 $s[i]$ 的下标。注意,这里的单调递增是指下标对应的前缀和的大小,而不是下标的大小。
58+
59+
为什么存的是下标呢?这是为了方便计算子数组的长度。那为什么队列严格单调递增?我们可以用反证法来说明。
60+
61+
假设队列元素非严格单调递增,也即是说,存在下标 $i$ 和 $j$,满足 $i < j$,且 $s[i] \geq s[j]$。
62+
63+
当遍历到下标 $k$,其中 $i \lt j \lt k \leq n$,此时 $s[k]-s[j] \geq s[k]-s[i]$,且 $nums[j..k-1]$ 的长度小于 $nums[i..k-1]$ 的长度。由于下标 $j$ 的存在,子数组 $nums[i..k-1]$ 一定不是最优解,队列中的下标 $i$ 是不必要的,需要将其移除。因此,队列中的元素一定严格单调递增。
64+
65+
回到这道题目上,我们遍历前缀和数组 $s$,对于遍历到的下标 $i$,如果 $s[i] - s[q.front] \geq k$,说明当前遇到了一个可行解,我们可以更新答案。此时,我们需要将队首元素出队,直到队列为空或者 $s[i] - s[q.front] \lt k$ 为止。
66+
67+
如果此时队列不为空,为了维持队列的严格单调递增,我们还需要判断队尾元素是否需要出队,如果 $s[q.back] \geq s[i]$,则需要循环将队尾元素出队,直到队列为空或者 $s[q.back] \lt s[i]$ 为止。然后,我们将下标 $i$ 入队。
68+
69+
遍历结束,如果我们没有找到可行解,那么返回 $-1$。否则,返回答案。
70+
71+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 `nums` 的长度。
5472

5573
<!-- tabs:start -->
5674

@@ -61,13 +79,13 @@
6179
```python
6280
class Solution:
6381
def shortestSubarray(self, nums: List[int], k: int) -> int:
64-
s = [0] + list(accumulate(nums))
82+
s = list(accumulate(nums, initial=0))
83+
q = deque()
6584
ans = inf
66-
q = deque([0])
67-
for i in range(1, len(s)):
68-
while q and s[i] - s[q[0]] >= k:
85+
for i, v in enumerate(s):
86+
while q and v - s[q[0]] >= k:
6987
ans = min(ans, i - q.popleft())
70-
while q and s[i] <= s[q[-1]]:
88+
while q and s[q[-1]] >= v:
7189
q.pop()
7290
q.append(i)
7391
return -1 if ans == inf else ans
@@ -86,18 +104,17 @@ class Solution {
86104
s[i + 1] = s[i] + nums[i];
87105
}
88106
Deque<Integer> q = new ArrayDeque<>();
89-
q.offer(0);
90-
int ans = Integer.MAX_VALUE;
91-
for (int i = 1; i <= n; ++i) {
107+
int ans = n + 1;
108+
for (int i = 0; i <= n; ++i) {
92109
while (!q.isEmpty() && s[i] - s[q.peek()] >= k) {
93110
ans = Math.min(ans, i - q.poll());
94111
}
95-
while (!q.isEmpty() && s[i] <= s[q.peekLast()]) {
112+
while (!q.isEmpty() && s[q.peekLast()] >= s[i]) {
96113
q.pollLast();
97114
}
98115
q.offer(i);
99116
}
100-
return ans == Integer.MAX_VALUE ? -1 : ans;
117+
return ans > n ? -1 : ans;
101118
}
102119
}
103120
```
@@ -109,19 +126,19 @@ class Solution {
109126
public:
110127
int shortestSubarray(vector<int>& nums, int k) {
111128
int n = nums.size();
112-
vector<long long> s(n + 1);
129+
vector<long> s(n + 1);
113130
for (int i = 0; i < n; ++i) s[i + 1] = s[i] + nums[i];
114-
deque<int> q {{0}};
115-
int ans = INT_MAX;
116-
for (int i = 1; i <= n; ++i) {
131+
deque<int> q;
132+
int ans = n + 1;
133+
for (int i = 0; i <= n; ++i) {
117134
while (!q.empty() && s[i] - s[q.front()] >= k) {
118135
ans = min(ans, i - q.front());
119136
q.pop_front();
120137
}
121-
while (!q.empty() && s[i] <= s[q.back()]) q.pop_back();
138+
while (!q.empty() && s[q.back()] >= s[i]) q.pop_back();
122139
q.push_back(i);
123140
}
124-
return ans == INT_MAX ? -1 : ans;
141+
return ans > n ? -1 : ans;
125142
}
126143
};
127144
```
@@ -132,22 +149,22 @@ public:
132149
func shortestSubarray(nums []int, k int) int {
133150
n := len(nums)
134151
s := make([]int, n+1)
135-
for i, v := range nums {
136-
s[i+1] = s[i] + v
152+
for i, x := range nums {
153+
s[i+1] = s[i] + x
137154
}
138-
q := []int{0}
139-
ans := math.MaxInt32
140-
for i := 1; i <= n; i++ {
141-
for len(q) > 0 && s[i]-s[q[0]] >= k {
155+
q := []int{}
156+
ans := n + 1
157+
for i, v := range s {
158+
for len(q) > 0 && v-s[q[0]] >= k {
142159
ans = min(ans, i-q[0])
143160
q = q[1:]
144161
}
145-
for len(q) > 0 && s[i] <= s[q[len(q)-1]] {
162+
for len(q) > 0 && s[q[len(q)-1]] >= v {
146163
q = q[:len(q)-1]
147164
}
148165
q = append(q, i)
149166
}
150-
if ans == math.MaxInt32 {
167+
if ans > n {
151168
return -1
152169
}
153170
return ans

solution/0800-0899/0862.Shortest Subarray with Sum at Least K/README_EN.md

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@
3737
```python
3838
class Solution:
3939
def shortestSubarray(self, nums: List[int], k: int) -> int:
40-
s = [0] + list(accumulate(nums))
40+
s = list(accumulate(nums, initial=0))
41+
q = deque()
4142
ans = inf
42-
q = deque([0])
43-
for i in range(1, len(s)):
44-
while q and s[i] - s[q[0]] >= k:
43+
for i, v in enumerate(s):
44+
while q and v - s[q[0]] >= k:
4545
ans = min(ans, i - q.popleft())
46-
while q and s[i] <= s[q[-1]]:
46+
while q and s[q[-1]] >= v:
4747
q.pop()
4848
q.append(i)
4949
return -1 if ans == inf else ans
@@ -60,18 +60,17 @@ class Solution {
6060
s[i + 1] = s[i] + nums[i];
6161
}
6262
Deque<Integer> q = new ArrayDeque<>();
63-
q.offer(0);
64-
int ans = Integer.MAX_VALUE;
65-
for (int i = 1; i <= n; ++i) {
63+
int ans = n + 1;
64+
for (int i = 0; i <= n; ++i) {
6665
while (!q.isEmpty() && s[i] - s[q.peek()] >= k) {
6766
ans = Math.min(ans, i - q.poll());
6867
}
69-
while (!q.isEmpty() && s[i] <= s[q.peekLast()]) {
68+
while (!q.isEmpty() && s[q.peekLast()] >= s[i]) {
7069
q.pollLast();
7170
}
7271
q.offer(i);
7372
}
74-
return ans == Integer.MAX_VALUE ? -1 : ans;
73+
return ans > n ? -1 : ans;
7574
}
7675
}
7776
```
@@ -83,19 +82,19 @@ class Solution {
8382
public:
8483
int shortestSubarray(vector<int>& nums, int k) {
8584
int n = nums.size();
86-
vector<long long> s(n + 1);
85+
vector<long> s(n + 1);
8786
for (int i = 0; i < n; ++i) s[i + 1] = s[i] + nums[i];
88-
deque<int> q {{0}};
89-
int ans = INT_MAX;
90-
for (int i = 1; i <= n; ++i) {
87+
deque<int> q;
88+
int ans = n + 1;
89+
for (int i = 0; i <= n; ++i) {
9190
while (!q.empty() && s[i] - s[q.front()] >= k) {
9291
ans = min(ans, i - q.front());
9392
q.pop_front();
9493
}
95-
while (!q.empty() && s[i] <= s[q.back()]) q.pop_back();
94+
while (!q.empty() && s[q.back()] >= s[i]) q.pop_back();
9695
q.push_back(i);
9796
}
98-
return ans == INT_MAX ? -1 : ans;
97+
return ans > n ? -1 : ans;
9998
}
10099
};
101100
```
@@ -106,22 +105,22 @@ public:
106105
func shortestSubarray(nums []int, k int) int {
107106
n := len(nums)
108107
s := make([]int, n+1)
109-
for i, v := range nums {
110-
s[i+1] = s[i] + v
108+
for i, x := range nums {
109+
s[i+1] = s[i] + x
111110
}
112-
q := []int{0}
113-
ans := math.MaxInt32
114-
for i := 1; i <= n; i++ {
115-
for len(q) > 0 && s[i]-s[q[0]] >= k {
111+
q := []int{}
112+
ans := n + 1
113+
for i, v := range s {
114+
for len(q) > 0 && v-s[q[0]] >= k {
116115
ans = min(ans, i-q[0])
117116
q = q[1:]
118117
}
119-
for len(q) > 0 && s[i] <= s[q[len(q)-1]] {
118+
for len(q) > 0 && s[q[len(q)-1]] >= v {
120119
q = q[:len(q)-1]
121120
}
122121
q = append(q, i)
123122
}
124-
if ans == math.MaxInt32 {
123+
if ans > n {
125124
return -1
126125
}
127126
return ans

solution/0800-0899/0862.Shortest Subarray with Sum at Least K/Solution.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ class Solution {
22
public:
33
int shortestSubarray(vector<int>& nums, int k) {
44
int n = nums.size();
5-
vector<long long> s(n + 1);
5+
vector<long> s(n + 1);
66
for (int i = 0; i < n; ++i) s[i + 1] = s[i] + nums[i];
7-
deque<int> q{{0}};
8-
int ans = INT_MAX;
9-
for (int i = 1; i <= n; ++i) {
7+
deque<int> q;
8+
int ans = n + 1;
9+
for (int i = 0; i <= n; ++i) {
1010
while (!q.empty() && s[i] - s[q.front()] >= k) {
1111
ans = min(ans, i - q.front());
1212
q.pop_front();
1313
}
14-
while (!q.empty() && s[i] <= s[q.back()]) q.pop_back();
14+
while (!q.empty() && s[q.back()] >= s[i]) q.pop_back();
1515
q.push_back(i);
1616
}
17-
return ans == INT_MAX ? -1 : ans;
17+
return ans > n ? -1 : ans;
1818
}
1919
};

solution/0800-0899/0862.Shortest Subarray with Sum at Least K/Solution.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
func shortestSubarray(nums []int, k int) int {
22
n := len(nums)
33
s := make([]int, n+1)
4-
for i, v := range nums {
5-
s[i+1] = s[i] + v
4+
for i, x := range nums {
5+
s[i+1] = s[i] + x
66
}
7-
q := []int{0}
8-
ans := math.MaxInt32
9-
for i := 1; i <= n; i++ {
10-
for len(q) > 0 && s[i]-s[q[0]] >= k {
7+
q := []int{}
8+
ans := n + 1
9+
for i, v := range s {
10+
for len(q) > 0 && v-s[q[0]] >= k {
1111
ans = min(ans, i-q[0])
1212
q = q[1:]
1313
}
14-
for len(q) > 0 && s[i] <= s[q[len(q)-1]] {
14+
for len(q) > 0 && s[q[len(q)-1]] >= v {
1515
q = q[:len(q)-1]
1616
}
1717
q = append(q, i)
1818
}
19-
if ans == math.MaxInt32 {
19+
if ans > n {
2020
return -1
2121
}
2222
return ans

solution/0800-0899/0862.Shortest Subarray with Sum at Least K/Solution.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,16 @@ public int shortestSubarray(int[] nums, int k) {
66
s[i + 1] = s[i] + nums[i];
77
}
88
Deque<Integer> q = new ArrayDeque<>();
9-
q.offer(0);
10-
int ans = Integer.MAX_VALUE;
11-
for (int i = 1; i <= n; ++i) {
9+
int ans = n + 1;
10+
for (int i = 0; i <= n; ++i) {
1211
while (!q.isEmpty() && s[i] - s[q.peek()] >= k) {
1312
ans = Math.min(ans, i - q.poll());
1413
}
15-
while (!q.isEmpty() && s[i] <= s[q.peekLast()]) {
14+
while (!q.isEmpty() && s[q.peekLast()] >= s[i]) {
1615
q.pollLast();
1716
}
1817
q.offer(i);
1918
}
20-
return ans == Integer.MAX_VALUE ? -1 : ans;
19+
return ans > n ? -1 : ans;
2120
}
2221
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
class Solution:
22
def shortestSubarray(self, nums: List[int], k: int) -> int:
3-
s = [0] + list(accumulate(nums))
3+
s = list(accumulate(nums, initial=0))
4+
q = deque()
45
ans = inf
5-
q = deque([0])
6-
for i in range(1, len(s)):
7-
while q and s[i] - s[q[0]] >= k:
6+
for i, v in enumerate(s):
7+
while q and v - s[q[0]] >= k:
88
ans = min(ans, i - q.popleft())
9-
while q and s[i] <= s[q[-1]]:
9+
while q and s[q[-1]] >= v:
1010
q.pop()
1111
q.append(i)
1212
return -1 if ans == inf else ans

0 commit comments

Comments
 (0)