@@ -76,27 +76,33 @@ nums[3] + nums[0] = 3 + 1 = 4.
7676
7777### 方法一:差分数组
7878
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$ 。
8080
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 ] $ 的较大值 。
8282
83- 如何求出对于不同的 $x$,需要替换的最少次数呢?
83+ 对于每一对数,我们有以下几种情况:
8484
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}$。
8688
87- - 如果 $x = a + b$,那么我们需要替换的次数为 $0$,即当前的数对已经满足互补的要求;
88- - 否则如果 $1 + a \le x \le limit + b $,那么我们需要替换的次数为 $1$,即把其中一个数替换即可;
89- - 否则如果 $2 \le x \le 2 \times limit$,那么我们需要替换的次数为 $2$,即把两个数都替换。
89+ 即:
9090
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$ 次。
9296
93- 1 . 先将 $[ 2,... 2 \times limit] $ 范围需要的操作次数加 $2$。
94- 1 . 再将 $[ 1 + a,... limit + b] $ 范围需要的操作次数减 $1$。
95- 1 . 最后将 $[ a + b,... a + b] $ 范围需要的操作次数减 $1$。
97+ 我们枚举每一个数对,利用差分数组,更新每个数对在不同区间范围内的替换次数。
9698
97- 可以发现,这实际上是在对一个连续区间内的元素进行加减操作,因此我们可以使用差分数组来实现 。
99+ 最后,我们求出下标 $2$ 到 $2 \times \textit{limit}$ 的前缀和中的最小值,即为最少的替换次数 。
98100
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 )
100106
101107<!-- tabs:start -->
102108
@@ -105,55 +111,44 @@ nums[3] + nums[0] = 3 + 1 = 4.
105111``` python
106112class Solution :
107113 def minMoves (self , nums : List[int ], limit : int ) -> int :
108- d = [0 ] * (limit * 2 + 2 )
114+ d = [0 ] * (2 * limit + 2 )
109115 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
114120 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 :]))
129128```
130129
131130#### Java
132131
133132``` java
134133class Solution {
135134 public int minMoves (int [] nums , int limit ) {
135+ int [] d = new int [2 * limit + 2 ];
136136 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 ]);
142140 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 ;
150147 }
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) {
153150 s += d[i];
154- if (ans > s) {
155- ans = s;
156- }
151+ ans = Math . min(ans, s);
157152 }
158153 return ans;
159154 }
@@ -167,26 +162,25 @@ class Solution {
167162public:
168163 int minMoves(vector<int >& nums, int limit) {
169164 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+ }
175172 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;
183179 }
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) {
186182 s += d[ i] ;
187- if (ans > s) {
188- ans = s;
189- }
183+ ans = min(ans, s);
190184 }
191185 return ans;
192186 }
@@ -197,25 +191,25 @@ public:
197191
198192```go
199193func minMoves(nums []int, limit int) int {
200- d := make ([]int , limit*2 +2 )
201194 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+ }
204201 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
212208 }
213209 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)
219213 }
220214 return ans
221215}
@@ -228,25 +222,21 @@ function minMoves(nums: number[], limit: number): number {
228222 const n = nums .length ;
229223 const d: number [] = Array (limit * 2 + 2 ).fill (0 );
230224 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 ]);
234227 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 ;
242234 }
243235 let ans = n ;
244236 let s = 0 ;
245- for (let i = 2 ; i <= limit * 2 ; ++ i ) {
237+ for (let i = 2 ; i < d . length ; ++ i ) {
246238 s += d [i ];
247- if (ans > s ) {
248- ans = s ;
249- }
239+ ans = Math .min (ans , s );
250240 }
251241 return ans ;
252242}
0 commit comments