Skip to content

Commit deb9ca3

Browse files
committed
feat: add solutions to lc problem: No.1818
No.1818.Minimum Absolute Sum Difference
1 parent a0aef0a commit deb9ca3

File tree

8 files changed

+441
-295
lines changed

8 files changed

+441
-295
lines changed

solution/1800-1899/1818.Minimum Absolute Sum Difference/README.md

Lines changed: 155 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,13 @@
6868

6969
**方法一:排序 + 二分查找**
7070

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` 的长度。
7278

7379
<!-- tabs:start -->
7480

@@ -79,27 +85,19 @@
7985
```python
8086
class Solution:
8187
def minAbsoluteSumDiff(self, nums1: List[int], nums2: List[int]) -> int:
82-
diff = [abs(a - b) for a, b in zip(nums1, nums2)]
8388
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
8991
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
103101
```
104102

105103
### **Java**
@@ -108,45 +106,34 @@ class Solution:
108106

109107
```java
110108
class Solution {
111-
private static final int MOD = (int) 1e9 + 7;
112-
113109
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;
117114
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;
123116
}
124-
Arrays.sort(nums1);
125117
int mx = 0;
126118
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]));
130124
}
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]));
136127
}
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);
142129
}
143-
return (s - mx + MOD) % MOD;
130+
return (s - mx + mod) % mod;
144131
}
145132

146133
private int search(int[] nums, int x) {
147134
int left = 0, right = nums.length;
148135
while (left < right) {
149-
int mid = (left + right) >> 1;
136+
int mid = (left + right) >>> 1;
150137
if (nums[mid] >= x) {
151138
right = mid;
152139
} else {
@@ -165,26 +152,24 @@ class Solution {
165152
public:
166153
int minAbsoluteSumDiff(vector<int>& nums1, vector<int>& nums2) {
167154
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();
171158
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;
174160
}
175-
if (s == 0) return 0;
176-
sort(nums1.begin(), nums1.end());
177161
int mx = 0;
178162
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);
188173
}
189174
return (s - mx + mod) % mod;
190175
}
@@ -195,51 +180,31 @@ public:
195180
196181
```go
197182
func minAbsoluteSumDiff(nums1 []int, nums2 []int) int {
198-
mod := int(1e9) + 7
199183
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
208192
}
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))
215199
}
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))
220202
}
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)
226204
}
227205
return (s - mx + mod) % mod
228206
}
229207
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-
243208
func max(a, b int) int {
244209
if a > b {
245210
return a
@@ -262,6 +227,97 @@ func abs(x int) int {
262227
}
263228
```
264229

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+
265321
### **...**
266322

267323
```

0 commit comments

Comments
 (0)