@@ -76,27 +76,33 @@ nums[3] + nums[0] = 3 + 1 = 4.
76
76
77
77
### 方法一:差分数组
78
78
79
- 我们不妨设 $a$ 为 $ nums[ i] $ 和 $nums[ n-i-1] $ 的较小值,设 $b$ 为 $nums [ i ] $ 和 $nums [ n-i-1 ] $ 的较大值 。
79
+ 假设最终的数组中,数对 $\textit{ nums} [ i] $ 和 $\textit{ nums} [ n-i-1] $ 的和为 $s$ 。
80
80
81
- 假设经过替换后,两数之和为 $x$。由题意,我们知道 $x$ 最小值为 $2$,即两个数替换为 $1$;最大值为 $2 \times limit$,即两个数都替换为 $limit$。因此 $x$ 的取值范围是 $ [ 2,... 2 \times limit ] $ 。
81
+ 我们不妨设 $x$ 为 $\textit{nums} [ i ] $ 和 $\textit{nums} [ n-i-1 ] $ 的较小值,设 $y$ 为 $\textit{nums} [ i ] $ 和 $\textit{nums} [ n-i-1 ] $ 的较大值 。
82
82
83
- 如何求出对于不同的 $x$,需要替换的最少次数呢?
83
+ 对于每一对数,我们有以下几种情况:
84
84
85
- 我们分析发现:
85
+ - 如果不需要替换,那么 $x + y = s$。
86
+ - 如果替换一次,那么 $x + 1 \le s \le y + \textit{limit}$。
87
+ - 如果替换两次,那么 $2 \le s \le x$ 或 $y + \textit{limit} + 1 \le s \le 2 \times \textit{limit}$。
86
88
87
- - 如果 $x = a + b$,那么我们需要替换的次数为 $0$,即当前的数对已经满足互补的要求;
88
- - 否则如果 $1 + a \le x \le limit + b $,那么我们需要替换的次数为 $1$,即把其中一个数替换即可;
89
- - 否则如果 $2 \le x \le 2 \times limit$,那么我们需要替换的次数为 $2$,即把两个数都替换。
89
+ 即:
90
90
91
- 因此,我们可以遍历每一对数,执行如下操作:
91
+ - 在 $[ 2,..x] $ 范围内,需要替换 $2$ 次。
92
+ - 在 $[ x+1,..x+y-1] $ 范围内,需要替换 $1$ 次。
93
+ - 在 $[ x+y] $ 时,不需要替换。
94
+ - 在 $[ x+y+1,..y + \textit{limit}] $ 范围内,需要替换 $1$ 次。
95
+ - 在 $[ y + \textit{limit} + 1,..2 \times \textit{limit}] $ 范围内,需要替换 $2$ 次。
92
96
93
- 1 . 先将 $[ 2,... 2 \times limit] $ 范围需要的操作次数加 $2$。
94
- 1 . 再将 $[ 1 + a,... limit + b] $ 范围需要的操作次数减 $1$。
95
- 1 . 最后将 $[ a + b,... a + b] $ 范围需要的操作次数减 $1$。
97
+ 我们枚举每一个数对,利用差分数组,更新每个数对在不同区间范围内的替换次数。
96
98
97
- 可以发现,这实际上是在对一个连续区间内的元素进行加减操作,因此我们可以使用差分数组来实现 。
99
+ 最后,我们求出下标 $2$ 到 $2 \times \textit{limit}$ 的前缀和中的最小值,即为最少的替换次数 。
98
100
99
- 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
101
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。
102
+
103
+ 相似题目:
104
+
105
+ - [ 3224. 使差值相等的最少数组改动次数] ( https://github.com/doocs/leetcode/blob/main/solution/3200-3299/3224.Minimum%20Array%20Changes%20to%20Make%20Differences%20Equal/README.md )
100
106
101
107
<!-- tabs:start -->
102
108
@@ -105,55 +111,44 @@ nums[3] + nums[0] = 3 + 1 = 4.
105
111
``` python
106
112
class Solution :
107
113
def minMoves (self , nums : List[int ], limit : int ) -> int :
108
- d = [0 ] * (limit * 2 + 2 )
114
+ d = [0 ] * (2 * limit + 2 )
109
115
n = len (nums)
110
-
111
- for i in range (n >> 1 ):
112
- a, b = min (nums[i], nums[n - i - 1 ]), max (nums[i], nums[n - i - 1 ])
113
-
116
+ for i in range (n // 2 ):
117
+ x, y = nums[i], nums[ - i - 1 ]
118
+ if x > y:
119
+ x, y = y, x
114
120
d[2 ] += 2
115
- d[limit * 2 + 1 ] -= 2
116
-
117
- d[a + 1 ] -= 1
118
- d[b + limit + 1 ] += 1
119
-
120
- d[a + b] -= 1
121
- d[a + b + 1 ] += 1
122
-
123
- ans, s = n, 0
124
- for v in d[2 : limit * 2 + 1 ]:
125
- s += v
126
- if ans > s:
127
- ans = s
128
- return ans
121
+ d[x + 1 ] -= 2
122
+ d[x + 1 ] += 1
123
+ d[x + y] -= 1
124
+ d[x + y + 1 ] += 1
125
+ d[y + limit + 1 ] -= 1
126
+ d[y + limit + 1 ] += 2
127
+ return min (accumulate(d[2 :]))
129
128
```
130
129
131
130
#### Java
132
131
133
132
``` java
134
133
class Solution {
135
134
public int minMoves (int [] nums , int limit ) {
135
+ int [] d = new int [2 * limit + 2 ];
136
136
int n = nums. length;
137
- int [] d = new int [limit * 2 + 2 ];
138
- for (int i = 0 ; i < n >> 1 ; ++ i) {
139
- int a = Math . min(nums[i], nums[n - i - 1 ]);
140
- int b = Math . max(nums[i], nums[n - i - 1 ]);
141
-
137
+ for (int i = 0 ; i < n / 2 ; ++ i) {
138
+ int x = Math . min(nums[i], nums[n - i - 1 ]);
139
+ int y = Math . max(nums[i], nums[n - i - 1 ]);
142
140
d[2 ] += 2 ;
143
- d[limit * 2 + 1 ] -= 2 ;
144
-
145
- d[a + 1 ] -= 1 ;
146
- d[b + limit + 1 ] += 1 ;
147
-
148
- d[a + b] -= 1 ;
149
- d[a + b + 1 ] += 1 ;
141
+ d[x + 1 ] -= 2 ;
142
+ d[x + 1 ] += 1 ;
143
+ d[x + y] -= 1 ;
144
+ d[x + y + 1 ] += 1 ;
145
+ d[y + limit + 1 ] -= 1 ;
146
+ d[y + limit + 1 ] += 2 ;
150
147
}
151
- int ans = n, s = 0 ;
152
- for (int i = 2 ; i <= limit * 2 ; ++ i) {
148
+ int ans = n;
149
+ for (int i = 2 , s = 0 ; i < d . length ; ++ i) {
153
150
s += d[i];
154
- if (ans > s) {
155
- ans = s;
156
- }
151
+ ans = Math . min(ans, s);
157
152
}
158
153
return ans;
159
154
}
@@ -167,26 +162,25 @@ class Solution {
167
162
public:
168
163
int minMoves(vector<int >& nums, int limit) {
169
164
int n = nums.size();
170
- vector<int > d(limit * 2 + 2);
171
- for (int i = 0; i < n >> 1; ++i) {
172
- int a = min(nums[ i] , nums[ n - i - 1] );
173
- int b = max(nums[ i] , nums[ n - i - 1] );
174
-
165
+ int d[ limit * 2 + 2] ;
166
+ memset(d, 0, sizeof(d));
167
+ for (int i = 0; i < n / 2; ++i) {
168
+ int x = nums[ i] , y = nums[ n - i - 1] ;
169
+ if (x > y) {
170
+ swap(x, y);
171
+ }
175
172
d[ 2] += 2;
176
- d[limit * 2 + 1] -= 2;
177
-
178
- d[a + 1] -= 1;
179
- d[b + limit + 1] += 1;
180
-
181
- d[a + b] -= 1;
182
- d[a + b + 1] += 1;
173
+ d[ x + 1] -= 2;
174
+ d[ x + 1] += 1;
175
+ d[ x + y] -= 1;
176
+ d[ x + y + 1] += 1;
177
+ d[ y + limit + 1] -= 1;
178
+ d[ y + limit + 1] += 2;
183
179
}
184
- int ans = n, s = 0 ;
185
- for (int i = 2 ; i <= limit * 2 ; ++i) {
180
+ int ans = n;
181
+ for (int i = 2, s = 0 ; i <= limit * 2; ++i) {
186
182
s += d[ i] ;
187
- if (ans > s) {
188
- ans = s;
189
- }
183
+ ans = min(ans, s);
190
184
}
191
185
return ans;
192
186
}
@@ -197,25 +191,25 @@ public:
197
191
198
192
```go
199
193
func minMoves(nums []int, limit int) int {
200
- d := make ([]int , limit*2 +2 )
201
194
n := len(nums)
202
- for i := 0 ; i < n>>1 ; i++ {
203
- a , b := min (nums[i], nums[n-i-1 ]), max (nums[i], nums[n-i-1 ])
195
+ d := make([]int, 2*limit+2)
196
+ for i := 0; i < n/2; i++ {
197
+ x, y := nums[i], nums[n-1-i]
198
+ if x > y {
199
+ x, y = y, x
200
+ }
204
201
d[2] += 2
205
- d[limit*2 +1 ] -= 2
206
-
207
- d[a+1 ] -= 1
208
- d[b+limit+1 ] += 1
209
-
210
- d[a+b] -= 1
211
- d[a+b+1 ] += 1
202
+ d[x+1] -= 2
203
+ d[x+1] += 1
204
+ d[x+y] -= 1
205
+ d[x+y+1] += 1
206
+ d[y+limit+1] -= 1
207
+ d[y+limit+1] += 2
212
208
}
213
209
ans, s := n, 0
214
- for _ , v := range d[2 : limit*2 +1 ] {
215
- s += v
216
- if ans > s {
217
- ans = s
218
- }
210
+ for _, x := range d[2:] {
211
+ s += x
212
+ ans = min(ans, s)
219
213
}
220
214
return ans
221
215
}
@@ -228,25 +222,21 @@ function minMoves(nums: number[], limit: number): number {
228
222
const n = nums .length ;
229
223
const d: number [] = Array (limit * 2 + 2 ).fill (0 );
230
224
for (let i = 0 ; i < n >> 1 ; ++ i ) {
231
- const a = Math .min (nums [i ], nums [n - i - 1 ]);
232
- const b = Math .max (nums [i ], nums [n - i - 1 ]);
233
-
225
+ const x = Math .min (nums [i ], nums [n - 1 - i ]);
226
+ const y = Math .max (nums [i ], nums [n - 1 - i ]);
234
227
d [2 ] += 2 ;
235
- d [limit * 2 + 1 ] -= 2 ;
236
-
237
- d [a + 1 ] -= 1 ;
238
- d [b + limit + 1 ] += 1 ;
239
-
240
- d [a + b ] -= 1 ;
241
- d [a + b + 1 ] += 1 ;
228
+ d [x + 1 ] -= 2 ;
229
+ d [x + 1 ] += 1 ;
230
+ d [x + y ] -= 1 ;
231
+ d [x + y + 1 ] += 1 ;
232
+ d [y + limit + 1 ] -= 1 ;
233
+ d [y + limit + 1 ] += 2 ;
242
234
}
243
235
let ans = n ;
244
236
let s = 0 ;
245
- for (let i = 2 ; i <= limit * 2 ; ++ i ) {
237
+ for (let i = 2 ; i < d . length ; ++ i ) {
246
238
s += d [i ];
247
- if (ans > s ) {
248
- ans = s ;
249
- }
239
+ ans = Math .min (ans , s );
250
240
}
251
241
return ans ;
252
242
}
0 commit comments