Skip to content

Commit ff7e015

Browse files
committed
feat: add solutions to lc problem: No.1775
No.1775.Equal Sum Arrays With Minimum Number of Operations
1 parent eb340e0 commit ff7e015

File tree

6 files changed

+374
-196
lines changed

6 files changed

+374
-196
lines changed

solution/1700-1799/1775.Equal Sum Arrays With Minimum Number of Operations/README.md

Lines changed: 173 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,31 @@
5454

5555
<!-- 这里可写通用的实现逻辑 -->
5656

57-
贪心 + 计数排序。
57+
**方法一:贪心 + 排序**
5858

59-
设 s1, s2 分别表示数组 nums1, nums2 的和。不失一般性,可以设 `s1 < s2`
59+
我们用 $s_1$ 和 $s_2$ 分别表示数组 `nums1``nums2` 的和
6060

61-
直观上看,要想使得操作次数最小,我们应当尽可能增加 nums1 中元素的值,同时尽可能减少 nums2 中元素的值,因此:
61+
如果 $s_1 = s_2$,则不需要任何操作,直接返回 $0$。否则,我们不妨设 $s_1 \lt s_2$,即 $nums_1$ 中的元素和小于 $nums_2$ 中的元素和,那么两个数组元素和的差值 $d=s_2-s_1$。
6262

63-
- nums1 中每个元素 x 可以增加的量为 `6-x ∈ [0,5]`
64-
- nums2 中每个元素 x 可以减少的量为 `x-1 ∈ [0,5]`
63+
要使得两个数组元素和相等,我们需要对 `nums1` 中的元素进行增大操作,对 `nums2` 中的元素进行减小操作。
6564

66-
`diff = s2 - s1`,我们要选出最少的元素,使得**在 nums1 中元素的增加量****nums2 中元素的减少量**之和大于等于 diff。因此我们可以贪心地从 5 这个增加/减少量开始递减地选取即可
65+
对于 `nums1` 中的每个元素 $v$,我们最多可以将其增大到 $6$,那么 $v$ 可以增大的量为 $6-v$。对于 `nums2` 中的每个元素 $v$,我们最多可以将其减小到 $1$,那么 $v$ 可以减小的量为 $v-1$
6766

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$。
6982

7083
<!-- tabs:start -->
7184

@@ -81,20 +94,32 @@ class Solution:
8194
return 0
8295
if s1 > s2:
8396
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
95121
ans += 1
96-
i -= 1
97-
return -1 if diff > 0 else ans
122+
return ans if d <= 0 else -1
98123
```
99124

100125
### **Java**
@@ -104,39 +129,63 @@ class Solution:
104129
```java
105130
class Solution {
106131
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();
109134
if (s1 == s2) {
110135
return 0;
111136
}
112137
if (s1 > s2) {
113138
return minOperations(nums2, nums1);
114139
}
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;
118145
}
119-
for (int x : nums2) {
120-
++freq[x - 1];
146+
for (int v : nums2) {
147+
arr[k++] = v - 1;
121148
}
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;
129154
}
130155
}
131-
return diff > 0 ? -1 : ans;
156+
return -1;
132157
}
158+
}
159+
```
133160

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+
}
138187
}
139-
return s;
188+
return d <= 0 ? ans : -1;
140189
}
141190
}
142191
```
@@ -151,19 +200,42 @@ public:
151200
int s2 = accumulate(nums2.begin(), nums2.end(), 0);
152201
if (s1 == s2) return 0;
153202
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];
158230
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];
163235
++ans;
164236
}
165237
}
166-
return diff > 0 ? -1 : ans;
238+
return d <= 0 ? ans : -1;
167239
}
168240
};
169241
```
@@ -179,34 +251,67 @@ func minOperations(nums1 []int, nums2 []int) int {
179251
if s1 > s2 {
180252
return minOperations(nums2, nums1)
181253
}
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]++
185293
}
186-
for _, x := range nums2 {
187-
freq[x-1]++
294+
for _, v := range nums2 {
295+
cnt[v-1]++
188296
}
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]--
195301
ans++
196302
}
197303
}
198-
if diff > 0 {
199-
return -1
304+
if d <= 0 {
305+
return
200306
}
201-
return ans
307+
return -1
202308
}
203309

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
208313
}
209-
return s
314+
return
210315
}
211316
```
212317

0 commit comments

Comments
 (0)