54
54
55
55
<!-- 这里可写通用的实现逻辑 -->
56
56
57
- 贪心 + 计数排序。
57
+ ** 方法一: 贪心 + 排序 **
58
58
59
- 设 s1, s2 分别表示数组 nums1, nums2 的和。不失一般性,可以设 ` s1 < s2 ` 。
59
+ 我们用 $s_1$ 和 $s_2$ 分别表示数组 ` nums1 ` 和 ` nums2 ` 的和 。
60
60
61
- 直观上看,要想使得操作次数最小,我们应当尽可能增加 nums1 中元素的值,同时尽可能减少 nums2 中元素的值,因此:
61
+ 如果 $s_1 = s_2$,则不需要任何操作,直接返回 $0$。否则,我们不妨设 $s_1 \lt s_2$,即 $nums_1$ 中的元素和小于 $nums_2$ 中的元素和,那么两个数组元素和的差值 $d=s_2-s_1$。
62
62
63
- - nums1 中每个元素 x 可以增加的量为 ` 6-x ∈ [0,5] `
64
- - nums2 中每个元素 x 可以减少的量为 ` x-1 ∈ [0,5] `
63
+ 要使得两个数组元素和相等,我们需要对 ` nums1 ` 中的元素进行增大操作,对 ` nums2 ` 中的元素进行减小操作。
65
64
66
- 记 ` diff = s2 - s1 ` ,我们要选出最少的元素,使得 ** 在 nums1 中元素的增加量 ** 与 ** 在 nums2 中元素的减少量 ** 之和大于等于 diff。因此我们可以贪心地从 5 这个增加/减少量开始递减地选取即可 。
65
+ 对于 ` nums1 ` 中的每个元素 $v$,我们最多可以将其增大到 $6$,那么 $v$ 可以增大的量为 $6-v$。对于 ` nums2 ` 中的每个元素 $v$,我们最多可以将其减小到 $1$,那么 $v$ 可以减小的量为 $v-1$ 。
67
66
68
- 在实际的代码编写中,我们只需要使用一个长度为 6 的数组,其下标为增加 / 减少量,值为对应的元素数量。
67
+ 我们将每个元素的变化量放入数组 ` arr ` 中,然后对数组 ` arr ` 进行降序排列。
68
+
69
+ 接下来,我们从数组 ` arr ` 的第一个元素开始,贪心地将 $d$ 减去每个元素的变化量,直到 $d \leq 0$,返回此时的操作次数即可。
70
+
71
+ 遍历结束后,如果 $d \gt 0$,说明无法使得两个数组元素和相等,返回 $-1$。
72
+
73
+ 时间复杂度 $O((m+n) \times \log (m + n))$,空间复杂度 $O(m+n)$。其中 $m$ 和 $n$ 分别为数组 ` nums1 ` 和 ` nums2 ` 的长度。
74
+
75
+ ** 方法二:贪心 + 计数排序**
76
+
77
+ 方法一中,我们需要创建数组 ` arr ` 并进行排序,时空复杂度较高。由于数组 ` arr ` 中元素的范围为 $[ 0,..5] $,因此我们创建一个长度为 $6$ 的数组 ` cnt ` ,用于统计数组 ` arr ` 中每个元素的数量,也即每个最大变化量的元素的数量。
78
+
79
+ 接下来,我们从最大变化量 $i=5$ 开始,贪心地将 $d$ 减去最大变化量,直到 $d \leq 0$,返回此时的操作次数即可。
80
+
81
+ 时间复杂度 $O(m+n)$,空间复杂度 $O(C)$。其中 $m$ 和 $n$ 分别为数组 ` nums1 ` 和 ` nums2 ` 的长度。本题中 $C=6$。
69
82
70
83
<!-- tabs:start -->
71
84
@@ -81,20 +94,32 @@ class Solution:
81
94
return 0
82
95
if s1 > s2:
83
96
return self .minOperations(nums2, nums1)
84
- freq = [0 ] * 6
85
- for x in nums1:
86
- freq[6 - x] += 1
87
- for x in nums2:
88
- freq[x - 1 ] += 1
89
- diff = s2 - s1
90
- ans, i = 0 , 5
91
- while i > 0 and diff > 0 :
92
- while freq[i] and diff > 0 :
93
- diff -= i
94
- freq[i] -= 1
97
+ arr = [6 - v for v in nums1] + [v - 1 for v in nums2]
98
+ d = s2 - s1
99
+ for i, v in enumerate (sorted (arr, reverse = True ), 1 ):
100
+ d -= v
101
+ if d <= 0 :
102
+ return i
103
+ return - 1
104
+ ```
105
+
106
+ ``` python
107
+ class Solution :
108
+ def minOperations (self , nums1 : List[int ], nums2 : List[int ]) -> int :
109
+ s1, s2 = sum (nums1), sum (nums2)
110
+ if s1 == s2:
111
+ return 0
112
+ if s1 > s2:
113
+ return self .minOperations(nums2, nums1)
114
+ cnt = Counter([6 - v for v in nums1] + [v - 1 for v in nums2])
115
+ d = s2 - s1
116
+ ans = 0
117
+ for i in range (5 , 0 , - 1 ):
118
+ while cnt[i] and d > 0 :
119
+ d -= i
120
+ cnt[i] -= 1
95
121
ans += 1
96
- i -= 1
97
- return - 1 if diff > 0 else ans
122
+ return ans if d <= 0 else - 1
98
123
```
99
124
100
125
### ** Java**
@@ -104,39 +129,63 @@ class Solution:
104
129
``` java
105
130
class Solution {
106
131
public int minOperations (int [] nums1 , int [] nums2 ) {
107
- int s1 = sum (nums1);
108
- int s2 = sum (nums2);
132
+ int s1 = Arrays . stream (nums1) . sum( );
133
+ int s2 = Arrays . stream (nums2) . sum( );
109
134
if (s1 == s2) {
110
135
return 0 ;
111
136
}
112
137
if (s1 > s2) {
113
138
return minOperations(nums2, nums1);
114
139
}
115
- int [] freq = new int [6 ];
116
- for (int x : nums1) {
117
- ++ freq[6 - x];
140
+ int d = s2 - s1;
141
+ int [] arr = new int [nums1. length + nums2. length];
142
+ int k = 0 ;
143
+ for (int v : nums1) {
144
+ arr[k++ ] = 6 - v;
118
145
}
119
- for (int x : nums2) {
120
- ++ freq[x - 1 ] ;
146
+ for (int v : nums2) {
147
+ arr[k ++ ] = v - 1 ;
121
148
}
122
- int diff = s2 - s1;
123
- int ans = 0 ;
124
- for (int i = 5 ; i > 0 && diff > 0 ; -- i) {
125
- while (freq[i] > 0 && diff > 0 ) {
126
- diff -= i;
127
- -- freq[i];
128
- ++ ans;
149
+ Arrays . sort(arr);
150
+ for (int i = 1 , j = arr. length - 1 ; j >= 0 ; ++ i, -- j) {
151
+ d -= arr[j];
152
+ if (d <= 0 ) {
153
+ return i;
129
154
}
130
155
}
131
- return diff > 0 ? - 1 : ans ;
156
+ return - 1 ;
132
157
}
158
+ }
159
+ ```
133
160
134
- private int sum (int [] nums ) {
135
- int s = 0 ;
136
- for (int x : nums) {
137
- s += x;
161
+ ``` java
162
+ class Solution {
163
+ public int minOperations (int [] nums1 , int [] nums2 ) {
164
+ int s1 = Arrays . stream(nums1). sum();
165
+ int s2 = Arrays . stream(nums2). sum();
166
+ if (s1 == s2) {
167
+ return 0 ;
168
+ }
169
+ if (s1 > s2) {
170
+ return minOperations(nums2, nums1);
171
+ }
172
+ int d = s2 - s1;
173
+ int [] cnt = new int [6 ];
174
+ for (int v : nums1) {
175
+ ++ cnt[6 - v];
176
+ }
177
+ for (int v : nums2) {
178
+ ++ cnt[v - 1 ];
179
+ }
180
+ int ans = 0 ;
181
+ for (int i = 5 ; i > 0 ; -- i) {
182
+ while (cnt[i] > 0 && d > 0 ) {
183
+ d -= i;
184
+ -- cnt[i];
185
+ ++ ans;
186
+ }
138
187
}
139
- return s ;
188
+ return d <= 0 ? ans : - 1 ;
140
189
}
141
190
}
142
191
```
@@ -151,19 +200,42 @@ public:
151
200
int s2 = accumulate(nums2.begin(), nums2.end(), 0);
152
201
if (s1 == s2) return 0;
153
202
if (s1 > s2) return minOperations(nums2, nums1);
154
- vector<int > freq(6);
155
- for (int x : nums1) ++freq[ 6 - x] ;
156
- for (int x : nums2) ++freq[ x - 1] ;
157
- int diff = s2 - s1;
203
+ int d = s2 - s1;
204
+ int arr[ nums1.size() + nums2.size()] ;
205
+ int k = 0;
206
+ for (int& v : nums1) arr[ k++] = 6 - v;
207
+ for (int& v : nums2) arr[ k++] = v - 1;
208
+ sort(arr, arr + k, greater<>());
209
+ for (int i = 0; i < k; ++i) {
210
+ d -= arr[ i] ;
211
+ if (d <= 0) return i + 1;
212
+ }
213
+ return -1;
214
+ }
215
+ };
216
+ ```
217
+
218
+ ```cpp
219
+ class Solution {
220
+ public:
221
+ int minOperations(vector<int>& nums1, vector<int>& nums2) {
222
+ int s1 = accumulate(nums1.begin(), nums1.end(), 0);
223
+ int s2 = accumulate(nums2.begin(), nums2.end(), 0);
224
+ if (s1 == s2) return 0;
225
+ if (s1 > s2) return minOperations(nums2, nums1);
226
+ int d = s2 - s1;
227
+ int cnt[6] = {0};
228
+ for (int& v : nums1) ++cnt[6 - v];
229
+ for (int& v : nums2) ++cnt[v - 1];
158
230
int ans = 0;
159
- for (int i = 5; i > 0 && diff > 0 ; --i) {
160
- while (freq [ i] && diff > 0) {
161
- diff -= i;
162
- --freq [ i] ;
231
+ for (int i = 5; i; --i) {
232
+ while (cnt [i] && d > 0) {
233
+ d -= i;
234
+ --cnt [i];
163
235
++ans;
164
236
}
165
237
}
166
- return diff > 0 ? -1 : ans ;
238
+ return d <= 0 ? ans : -1 ;
167
239
}
168
240
};
169
241
```
@@ -179,34 +251,67 @@ func minOperations(nums1 []int, nums2 []int) int {
179
251
if s1 > s2 {
180
252
return minOperations (nums2, nums1)
181
253
}
182
- freq := make([]int, 6)
183
- for _, x := range nums1 {
184
- freq[6-x]++
254
+ d := s2 - s1
255
+ arr := []int {}
256
+ for _ , v := range nums1 {
257
+ arr = append (arr, 6 -v)
258
+ }
259
+ for _ , v := range nums2 {
260
+ arr = append (arr, v-1 )
261
+ }
262
+ sort.Sort (sort.Reverse (sort.IntSlice (arr)))
263
+ for i , v := range arr {
264
+ d -= v
265
+ if d <= 0 {
266
+ return i + 1
267
+ }
268
+ }
269
+ return -1
270
+ }
271
+
272
+ func sum (nums []int ) (s int ) {
273
+ for _ , v := range nums {
274
+ s += v
275
+ }
276
+ return
277
+ }
278
+ ```
279
+
280
+ ``` go
281
+ func minOperations (nums1 []int , nums2 []int ) (ans int ) {
282
+ s1 , s2 := sum (nums1), sum (nums2)
283
+ if s1 == s2 {
284
+ return 0
285
+ }
286
+ if s1 > s2 {
287
+ return minOperations (nums2, nums1)
288
+ }
289
+ d := s2 - s1
290
+ cnt := [6 ]int {}
291
+ for _ , v := range nums1 {
292
+ cnt[6 -v]++
185
293
}
186
- for _, x := range nums2 {
187
- freq[x -1]++
294
+ for _ , v := range nums2 {
295
+ cnt[v -1 ]++
188
296
}
189
- diff := s2 - s1
190
- ans := 0
191
- for i := 5; i > 0 && diff > 0; i-- {
192
- for freq[i] > 0 && diff > 0 {
193
- diff -= i
194
- freq[i]--
297
+ for i := 5 ; i > 0 ; i-- {
298
+ for cnt[i] > 0 && d > 0 {
299
+ d -= i
300
+ cnt[i]--
195
301
ans++
196
302
}
197
303
}
198
- if diff > 0 {
199
- return -1
304
+ if d <= 0 {
305
+ return
200
306
}
201
- return ans
307
+ return - 1
202
308
}
203
309
204
- func sum(nums []int) int {
205
- s := 0
206
- for _, x := range nums {
207
- s += x
310
+ func sum (nums []int ) (s int ) {
311
+ for _ , v := range nums {
312
+ s += v
208
313
}
209
- return s
314
+ return
210
315
}
211
316
```
212
317
0 commit comments