68
68
69
69
** 方法一:排序 + 二分查找**
70
70
71
- 时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$。
71
+ 根据题意,我们可以先计算出在不进行替换的情况下,` nums1 ` 和 ` nums2 ` 的绝对差值和,记为 $s$。
72
+
73
+ 接下来,我们枚举 ` nums1 ` 中的每个元素 $nums1[ i] $,将其替换为与 $nums2[ i] $ 最接近的元素,并且这个最接近的元素在 ` nums1 ` 中。因此,我们可以在枚举之前,先复制一份 ` nums1 ` ,得到数组 ` nums ` ,并将 ` nums ` 排序。接下来,就在 ` nums ` 中二分查找与 $nums2[ i] $ 最接近的元素,记为 $nums[ j] $,并计算 $|nums1[ i] - nums2[ i] | - |nums[ j] - nums2[ i] |$,更新差值 $mx$ 的最大值。
74
+
75
+ 最后,我们将 $s$ 减去 $mx$,即为答案。注意取模操作。
76
+
77
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 ` nums1 ` 的长度。
72
78
73
79
<!-- tabs:start -->
74
80
79
85
``` python
80
86
class Solution :
81
87
def minAbsoluteSumDiff (self , nums1 : List[int ], nums2 : List[int ]) -> int :
82
- diff = [abs (a - b) for a, b in zip (nums1, nums2)]
83
88
mod = 10 ** 9 + 7
84
- s = sum (diff)
85
- if s == 0 :
86
- return 0
87
- nums1.sort()
88
- n = len (nums1)
89
+ nums = sorted (nums1)
90
+ s = sum (abs (a - b) for a, b in zip (nums1, nums2)) % mod
89
91
mx = 0
90
- for i, b in enumerate (nums2):
91
- d = diff[i]
92
- if d == 0 :
93
- continue
94
- idx = bisect_left(nums1, b)
95
- a1 = a2 = 10 ** 6
96
- if idx != n:
97
- a1 = nums1[idx]
98
- if idx:
99
- a2 = nums1[idx - 1 ]
100
- c = min (abs (b - a1), abs (b - a2))
101
- mx = max (mx, d - c)
102
- return (s - mx) % mod
92
+ for i, (a, b) in enumerate (zip (nums1, nums2)):
93
+ d1, d2 = abs (a - b), inf
94
+ i = bisect_left(nums, b)
95
+ if i < len (nums):
96
+ d2 = min (d2, abs (nums[i] - b))
97
+ if i:
98
+ d2 = min (d2, abs (nums[i - 1 ] - b))
99
+ mx = max (mx, d1 - d2)
100
+ return (s - mx + mod) % mod
103
101
```
104
102
105
103
### ** Java**
@@ -108,45 +106,34 @@ class Solution:
108
106
109
107
``` java
110
108
class Solution {
111
- private static final int MOD = (int ) 1e9 + 7 ;
112
-
113
109
public int minAbsoluteSumDiff (int [] nums1 , int [] nums2 ) {
114
- int n = nums1. length;
115
- int [] diff = new int [n];
116
- int s = 0 ;
110
+ final int mod = (int ) 1e9 + 7 ;
111
+ int [] nums = nums1. clone();
112
+ Arrays . sort(nums);
113
+ int s = 0 , n = nums. length;
117
114
for (int i = 0 ; i < n; ++ i) {
118
- diff[i] = Math . abs(nums1[i] - nums2[i]);
119
- s = (s + diff[i]) % MOD ;
120
- }
121
- if (s == 0 ) {
122
- return 0 ;
115
+ s = (s + Math . abs(nums1[i] - nums2[i])) % mod;
123
116
}
124
- Arrays . sort(nums1);
125
117
int mx = 0 ;
126
118
for (int i = 0 ; i < n; ++ i) {
127
- int d = diff[i];
128
- if (d == 0 ) {
129
- continue ;
119
+ int d1 = Math . abs(nums1[i] - nums2[i]);
120
+ int d2 = 1 << 30 ;
121
+ int j = search(nums, nums2[i]);
122
+ if (j < n) {
123
+ d2 = Math . min(d2, Math . abs(nums[j] - nums2[i]));
130
124
}
131
- int b = nums2[i];
132
- int idx = search(nums1, b);
133
- int a1 = 1000000 , a2 = 1000000 ;
134
- if (idx != n) {
135
- a1 = nums1[idx];
125
+ if (j > 0 ) {
126
+ d2 = Math . min(d2, Math . abs(nums[j - 1 ] - nums2[i]));
136
127
}
137
- if (idx != 0 ) {
138
- a2 = nums1[idx - 1 ];
139
- }
140
- int c = Math . min(Math . abs(b - a1), Math . abs(b - a2));
141
- mx = Math . max(mx, d - c);
128
+ mx = Math . max(mx, d1 - d2);
142
129
}
143
- return (s - mx + MOD ) % MOD ;
130
+ return (s - mx + mod ) % mod ;
144
131
}
145
132
146
133
private int search (int [] nums , int x ) {
147
134
int left = 0 , right = nums. length;
148
135
while (left < right) {
149
- int mid = (left + right) >> 1 ;
136
+ int mid = (left + right) >>> 1 ;
150
137
if (nums[mid] >= x) {
151
138
right = mid;
152
139
} else {
@@ -165,26 +152,24 @@ class Solution {
165
152
public:
166
153
int minAbsoluteSumDiff(vector<int >& nums1, vector<int >& nums2) {
167
154
const int mod = 1e9 + 7;
168
- int n = nums1.size( );
169
- vector< int > diff(n );
170
- int s = 0;
155
+ vector< int > nums(nums1 );
156
+ sort(nums.begin(), nums.end() );
157
+ int s = 0, n = nums.size() ;
171
158
for (int i = 0; i < n; ++i) {
172
- diff[ i] = abs(nums1[ i] - nums2[ i] );
173
- s = (s + diff[ i] ) % mod;
159
+ s = (s + abs(nums1[ i] - nums2[ i] )) % mod;
174
160
}
175
- if (s == 0) return 0;
176
- sort(nums1.begin(), nums1.end());
177
161
int mx = 0;
178
162
for (int i = 0; i < n; ++i) {
179
- int d = diff[ i] ;
180
- if (d == 0) continue;
181
- int b = nums2[ i] ;
182
- int idx = lower_bound(nums1.begin(), nums1.end(), b) - nums1.begin();
183
- int a1 = 1e6, a2 = 1e6;
184
- if (idx != n) a1 = nums1[ idx] ;
185
- if (idx != 0) a2 = nums1[ idx - 1] ;
186
- int c = min(abs(b - a1), abs(b - a2));
187
- mx = max(mx, d - c);
163
+ int d1 = abs(nums1[ i] - nums2[ i] );
164
+ int d2 = 1 << 30;
165
+ int j = lower_bound(nums.begin(), nums.end(), nums2[ i] ) - nums.begin();
166
+ if (j < n) {
167
+ d2 = min(d2, abs(nums[ j] - nums2[ i] ));
168
+ }
169
+ if (j) {
170
+ d2 = min(d2, abs(nums[ j - 1] - nums2[ i] ));
171
+ }
172
+ mx = max(mx, d1 - d2);
188
173
}
189
174
return (s - mx + mod) % mod;
190
175
}
@@ -195,51 +180,31 @@ public:
195
180
196
181
```go
197
182
func minAbsoluteSumDiff(nums1 []int, nums2 []int) int {
198
- mod := int(1e9) + 7
199
183
n := len(nums1)
200
- diff := make([]int, n)
201
- s := 0
202
- for i := 0; i < n; i++ {
203
- diff[i] = abs(nums1[i] - nums2[i])
204
- s = (s + diff[i]) % mod
205
- }
206
- if s == 0 {
207
- return 0
184
+ nums := make([]int, n)
185
+ copy(nums, nums1)
186
+ sort.Ints(nums)
187
+ s, mx := 0, 0
188
+ const mod int = 1e9 + 7
189
+ for i, a := range nums1 {
190
+ b := nums2[i]
191
+ s = (s + abs(a-b)) % mod
208
192
}
209
- sort.Ints( nums1)
210
- mx := 0
211
- for i, b := range nums2 {
212
- d := diff[i]
213
- if d == 0 {
214
- continue
193
+ for i, a := range nums1 {
194
+ b := nums2[i]
195
+ d1, d2 := abs(a-b), 1<<30
196
+ j := sort.Search(n, func(k int) bool { return nums[k] >= b })
197
+ if j < n {
198
+ d2 = min(d2, abs(nums[j]-b))
215
199
}
216
- idx := search(nums1, b)
217
- a1, a2 := 1000000, 1000000
218
- if idx != n {
219
- a1 = nums1[idx]
200
+ if j > 0 {
201
+ d2 = min(d2, abs(nums[j-1]-b))
220
202
}
221
- if idx != 0 {
222
- a2 = nums1[idx-1]
223
- }
224
- c := min(abs(b-a1), abs(b-a2))
225
- mx = max(mx, d-c)
203
+ mx = max(mx, d1-d2)
226
204
}
227
205
return (s - mx + mod) % mod
228
206
}
229
207
230
- func search(nums []int, x int) int {
231
- left, right := 0, len(nums)
232
- for left < right {
233
- mid := (left + right) >> 1
234
- if nums[mid] >= x {
235
- right = mid
236
- } else {
237
- left = mid + 1
238
- }
239
- }
240
- return left
241
- }
242
-
243
208
func max(a, b int) int {
244
209
if a > b {
245
210
return a
@@ -262,6 +227,97 @@ func abs(x int) int {
262
227
}
263
228
```
264
229
230
+ ### ** JavaScript**
231
+
232
+ ``` js
233
+ /**
234
+ * @param {number[]} nums1
235
+ * @param {number[]} nums2
236
+ * @return {number}
237
+ */
238
+ var minAbsoluteSumDiff = function (nums1 , nums2 ) {
239
+ const mod = 10 ** 9 + 7 ;
240
+ const nums = [... nums1];
241
+ nums .sort ((a , b ) => a - b);
242
+ const n = nums .length ;
243
+ let s = 0 ;
244
+ for (let i = 0 ; i < n; ++ i) {
245
+ s = (s + Math .abs (nums1[i] - nums2[i])) % mod;
246
+ }
247
+ let mx = 0 ;
248
+ for (let i = 0 ; i < n; ++ i) {
249
+ const d1 = Math .abs (nums1[i] - nums2[i]);
250
+ let d2 = 1 << 30 ;
251
+ let j = search (nums, nums2[i]);
252
+ if (j < n) {
253
+ d2 = Math .min (d2, Math .abs (nums[j] - nums2[i]));
254
+ }
255
+ if (j) {
256
+ d2 = Math .min (d2, Math .abs (nums[j - 1 ] - nums2[i]));
257
+ }
258
+ mx = Math .max (mx, d1 - d2);
259
+ }
260
+ return (s - mx + mod) % mod;
261
+ };
262
+
263
+ function search (nums , x ) {
264
+ let left = 0 ;
265
+ let right = nums .length ;
266
+ while (left < right) {
267
+ const mid = (left + right) >> 1 ;
268
+ if (nums[mid] >= x) {
269
+ right = mid;
270
+ } else {
271
+ left = mid + 1 ;
272
+ }
273
+ }
274
+ return left;
275
+ }
276
+ ```
277
+
278
+ ### ** TypeScript**
279
+
280
+ ``` ts
281
+ function minAbsoluteSumDiff(nums1 : number [], nums2 : number []): number {
282
+ const mod = 10 ** 9 + 7 ;
283
+ const nums = [... nums1 ];
284
+ nums .sort ((a , b ) => a - b );
285
+ const n = nums .length ;
286
+ let s = 0 ;
287
+ for (let i = 0 ; i < n ; ++ i ) {
288
+ s = (s + Math .abs (nums1 [i ] - nums2 [i ])) % mod ;
289
+ }
290
+ let mx = 0 ;
291
+ for (let i = 0 ; i < n ; ++ i ) {
292
+ const d1 = Math .abs (nums1 [i ] - nums2 [i ]);
293
+ let d2 = 1 << 30 ;
294
+ let j = search (nums , nums2 [i ]);
295
+ if (j < n ) {
296
+ d2 = Math .min (d2 , Math .abs (nums [j ] - nums2 [i ]));
297
+ }
298
+ if (j ) {
299
+ d2 = Math .min (d2 , Math .abs (nums [j - 1 ] - nums2 [i ]));
300
+ }
301
+ mx = Math .max (mx , d1 - d2 );
302
+ }
303
+ return (s - mx + mod ) % mod ;
304
+ }
305
+
306
+ function search(nums : number [], x : number ): number {
307
+ let left = 0 ;
308
+ let right = nums .length ;
309
+ while (left < right ) {
310
+ const mid = (left + right ) >> 1 ;
311
+ if (nums [mid ] >= x ) {
312
+ right = mid ;
313
+ } else {
314
+ left = mid + 1 ;
315
+ }
316
+ }
317
+ return left ;
318
+ }
319
+ ```
320
+
265
321
### ** ...**
266
322
267
323
```
0 commit comments