49
49
50
50
<!-- 这里可写通用的实现逻辑 -->
51
51
52
- 前缀和 + 哈希表。
52
+ ** 方法一:哈希表 + 前缀和 **
53
53
54
- 题目可以转换为求中间连续子数组的最大长度,使得子数组的和为 ` sum(nums) - x ` 。
54
+ 我们可以将问题转换为求中间连续子数组的最大长度,使得子数组的和为 $x = sum(nums) - x$。
55
+
56
+ 定义一个哈希表 ` vis ` ,其中 ` vis[s] ` 表示前缀和为 $s$ 的最小下标。
57
+
58
+ 遍历数组 ` nums ` ,对于每个元素 $nums[ i] $,我们先将 $nums[ i] $ 加到前缀和 $s$ 上,如果哈希表中不存在 $s$,则将其加入哈希表,其值为当前下标 $i$。然后我们判断 $s - x$ 是否在哈希表中,如果存在,则说明存在一个下标 $j$,使得 $nums[ j + 1,..i] $ 的和为 $x$,此时我们更新答案的最小值,即 $ans = min(ans, n - (i - j))$。
59
+
60
+ 遍历结束,如果找不到满足条件的子数组,返回 $-1$,否则返回 $ans$。
61
+
62
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 ` nums ` 的长度。
63
+
64
+ ** 方法二:双指针**
65
+
66
+ 与方法一类似,我们要找到一个子数组,使得子数组的和为 $x = sum(nums) - x$。
67
+
68
+ 定义两个指针 $j$ 和 $i$,初始时 $i = j = 0$,然后我们向右移动指针 $i$,将 $nums[ i] $ 加到前缀和 $s$ 上。如果 $s \gt x$,那么我们循环向右移动指针 $j$,并且将 $nums[ j] $ 从前缀和 $s$ 上减去,直到 $s \le x$。如果 $s = x$,我们可以更新答案的最小值,即 $ans = min(ans, n - (i - j + 1))$。继续向右移动指针 $i$,重复上述过程。
69
+
70
+ 最后,如果找不到满足条件的子数组,返回 $-1$,否则返回 $ans$。
71
+
72
+ 时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 ` nums ` 的长度。
55
73
56
74
<!-- tabs:start -->
57
75
63
81
class Solution :
64
82
def minOperations (self , nums : List[int ], x : int ) -> int :
65
83
x = sum (nums) - x
66
- n = len (nums)
67
- s = 0
68
- seen = {0 : - 1 }
84
+ vis = {0 : - 1 }
69
85
ans = inf
86
+ s, n = 0 , len (nums)
70
87
for i, v in enumerate (nums):
71
88
s += v
72
- if s not in seen :
73
- seen [s] = i
74
- if s - x in seen :
75
- j = seen [s - x]
89
+ if s not in vis :
90
+ vis [s] = i
91
+ if s - x in vis :
92
+ j = vis [s - x]
76
93
ans = min (ans, n - (i - j))
77
94
return - 1 if ans == inf else ans
78
95
```
79
96
97
+ ``` python
98
+ class Solution :
99
+ def minOperations (self , nums : List[int ], x : int ) -> int :
100
+ x = sum (nums) - x
101
+ ans = inf
102
+ n = len (nums)
103
+ s = j = 0
104
+ for i, v in enumerate (nums):
105
+ s += v
106
+ while j <= i and s > x:
107
+ s -= nums[j]
108
+ j += 1
109
+ if s == x:
110
+ ans = min (ans, n - (i - j + 1 ))
111
+ return - 1 if ans == inf else ans
112
+ ```
113
+
80
114
### ** Java**
81
115
82
116
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -88,20 +122,42 @@ class Solution {
88
122
for (int v : nums) {
89
123
x += v;
90
124
}
91
- int s = 0 ;
125
+ Map<Integer , Integer > vis = new HashMap<> ();
126
+ vis. put(0 , - 1 );
92
127
int n = nums. length;
93
- Map<Integer , Integer > seen = new HashMap<> ();
94
- seen. put(0 , - 1 );
95
- int ans = Integer . MAX_VALUE ;
96
- for (int i = 0 ; i < n; ++ i) {
128
+ int ans = 1 << 30 ;
129
+ for (int i = 0 , s = 0 ; i < n; ++ i) {
97
130
s += nums[i];
98
- seen . putIfAbsent(s, i);
99
- if (seen . containsKey(s - x)) {
100
- int j = seen . get(s - x);
131
+ vis . putIfAbsent(s, i);
132
+ if (vis . containsKey(s - x)) {
133
+ int j = vis . get(s - x);
101
134
ans = Math . min(ans, n - (i - j));
102
135
}
103
136
}
104
- return ans == Integer . MAX_VALUE ? - 1 : ans;
137
+ return ans == 1 << 30 ? - 1 : ans;
138
+ }
139
+ }
140
+ ```
141
+
142
+ ``` java
143
+ class Solution {
144
+ public int minOperations (int [] nums , int x ) {
145
+ x = - x;
146
+ for (int v : nums) {
147
+ x += v;
148
+ }
149
+ int n = nums. length;
150
+ int ans = 1 << 30 ;
151
+ for (int i = 0 , j = 0 , s = 0 ; i < n; ++ i) {
152
+ s += nums[i];
153
+ while (j <= i && s > x) {
154
+ s -= nums[j++ ];
155
+ }
156
+ if (s == x) {
157
+ ans = Math . min(ans, n - (i - j + 1 ));
158
+ }
159
+ }
160
+ return ans == 1 << 30 ? - 1 : ans;
105
161
}
106
162
}
107
163
```
@@ -112,21 +168,42 @@ class Solution {
112
168
class Solution {
113
169
public:
114
170
int minOperations(vector<int >& nums, int x) {
115
- x = -x;
116
- for (int& v : nums) x += v;
117
- int s = 0, n = nums.size();
118
- unordered_map<int, int> seen;
119
- seen[ 0] = -1;
120
- int ans = INT_MAX;
121
- for (int i = 0; i < n; ++i) {
171
+ x = accumulate(nums.begin(), nums.end(), 0) - x;
172
+ unordered_map<int, int> vis{{0, -1}};
173
+ int n = nums.size();
174
+ int ans = 1 << 30;
175
+ for (int i = 0, s = 0; i < n; ++i) {
122
176
s += nums[ i] ;
123
- if (!seen.count(s)) seen[ s] = i;
124
- if (seen.count(s - x)) {
125
- int j = seen[ s - x] ;
177
+ if (!vis.count(s)) {
178
+ vis[ s] = i;
179
+ }
180
+ if (vis.count(s - x)) {
181
+ int j = vis[ s - x] ;
126
182
ans = min(ans, n - (i - j));
127
183
}
128
184
}
129
- return ans == INT_MAX ? -1 : ans;
185
+ return ans == 1 << 30 ? -1 : ans;
186
+ }
187
+ };
188
+ ```
189
+
190
+ ```cpp
191
+ class Solution {
192
+ public:
193
+ int minOperations(vector<int>& nums, int x) {
194
+ x = accumulate(nums.begin(), nums.end(), 0) - x;
195
+ int n = nums.size();
196
+ int ans = 1 << 30;
197
+ for (int i = 0, j = 0, s = 0; i < n; ++i) {
198
+ s += nums[i];
199
+ while (j <= i && s > x) {
200
+ s -= nums[j++];
201
+ }
202
+ if (s == x) {
203
+ ans = min(ans, n - (i - j + 1));
204
+ }
205
+ }
206
+ return ans == 1 << 30 ? -1 : ans;
130
207
}
131
208
};
132
209
```
@@ -139,19 +216,52 @@ func minOperations(nums []int, x int) int {
139
216
for _ , v := range nums {
140
217
x += v
141
218
}
219
+ vis := map [int ]int {0 : -1 }
220
+ ans := 1 << 30
142
221
s , n := 0 , len (nums)
143
- seen := map[int]int{0: -1}
144
- ans := math.MaxInt32
145
222
for i , v := range nums {
146
223
s += v
147
- if _, ok := seen [s]; !ok {
148
- seen [s] = i
224
+ if _ , ok := vis [s]; !ok {
225
+ vis [s] = i
149
226
}
150
- if j, ok := seen [s-x]; ok {
227
+ if j , ok := vis [s-x]; ok {
151
228
ans = min (ans, n-(i-j))
152
229
}
153
230
}
154
- if ans == math.MaxInt32 {
231
+ if ans == 1 <<30 {
232
+ return -1
233
+ }
234
+ return ans
235
+ }
236
+
237
+ func min (a , b int ) int {
238
+ if a < b {
239
+ return a
240
+ }
241
+ return b
242
+ }
243
+ ```
244
+
245
+ ``` go
246
+ func minOperations (nums []int , x int ) int {
247
+ x = -x
248
+ for _ , v := range nums {
249
+ x += v
250
+ }
251
+ ans := 1 << 30
252
+ s , n := 0 , len (nums)
253
+ j := 0
254
+ for i , v := range nums {
255
+ s += v
256
+ for j <= i && s > x {
257
+ s -= nums[j]
258
+ j++
259
+ }
260
+ if s == x {
261
+ ans = min (ans, n-(i-j+1 ))
262
+ }
263
+ }
264
+ if ans == 1 <<30 {
155
265
return -1
156
266
}
157
267
return ans
@@ -169,26 +279,40 @@ func min(a, b int) int {
169
279
170
280
``` ts
171
281
function minOperations(nums : number [], x : number ): number {
172
- const total = nums .reduce ((a , c ) => a + c , 0 );
173
- if (total < x ) return - 1 ;
174
- // 前缀和 + 哈希表, 求何为total - x的最长子序列
282
+ x = nums .reduce ((a , b ) => a + b , 0 ) - x ;
283
+ const vis = new Map ();
284
+ vis .set (0 , - 1 );
285
+ const n = nums .length ;
286
+ let ans = 1 << 30 ;
287
+ for (let i = 0 , s = 0 ; i < n ; ++ i ) {
288
+ s += nums [i ];
289
+ if (! vis .has (s )) {
290
+ vis .set (s , i );
291
+ }
292
+ if (vis .has (s - x )) {
293
+ const j = vis .get (s - x );
294
+ ans = Math .min (ans , n - (i - j ));
295
+ }
296
+ }
297
+ return ans == 1 << 30 ? - 1 : ans ;
298
+ }
299
+ ```
300
+
301
+ ``` ts
302
+ function minOperations(nums : number [], x : number ): number {
303
+ x = nums .reduce ((a , b ) => a + b , 0 ) - x ;
175
304
const n = nums .length ;
176
- const target = total - x ;
177
- let hashMap = new Map ();
178
- hashMap .set (0 , - 1 );
179
- let pre = 0 ;
180
- let ans = - 1 ;
181
- for (let right = 0 ; right < n ; right ++ ) {
182
- pre += nums [right ];
183
- if (! hashMap .has (pre )) {
184
- hashMap .set (pre , right );
305
+ let ans = 1 << 30 ;
306
+ for (let i = 0 , j = 0 , s = 0 ; i < n ; ++ i ) {
307
+ s += nums [i ];
308
+ while (j <= i && s > x ) {
309
+ s -= nums [j ++ ];
185
310
}
186
- if (hashMap .has (pre - target )) {
187
- let left = hashMap .get (pre - target );
188
- ans = Math .max (right - left , ans );
311
+ if (s == x ) {
312
+ ans = Math .min (ans , n - (i - j + 1 ));
189
313
}
190
314
}
191
- return ans == - 1 ? - 1 : n - ans ;
315
+ return ans == 1 << 30 ? - 1 : ans ;
192
316
}
193
317
```
194
318
0 commit comments