Skip to content

Commit 923471e

Browse files
authored
feat: update solutions to lc problem: No.2208 (doocs#1296)
No.2208.Minimum Operations to Halve Array Sum
1 parent ce40f1d commit 923471e

File tree

5 files changed

+142
-68
lines changed

5 files changed

+142
-68
lines changed

solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README.md

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ nums 的和减小了 31 - 14.5 = 16.5 ,减小的部分超过了初始数组和
5555

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

58+
**方法一:贪心 + 优先队列(大根堆)**
59+
60+
根据题目描述,每一次操作,都会将数组中的一个数减半。要使得数组和至少减少一半的操作次数最少,那么每一次操作都应该选择当前数组中的最大值进行减半。
61+
62+
因此,我们先算出数组要减少的总和 $s$,然后用一个优先队列(大根堆)维护数组中的所有数,每次从优先队列中取出最大值 $t$,将其减半,然后将减半后的数重新放入优先队列中,同时更新 $s$,直到 $s \le 0$ 为止。那么此时的操作次数就是答案。
63+
64+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。
65+
5866
<!-- tabs:start -->
5967

6068
### **Python3**
@@ -84,17 +92,17 @@ class Solution:
8492
```java
8593
class Solution {
8694
public int halveArray(int[] nums) {
87-
long s = 0;
95+
double s = 0;
8896
PriorityQueue<Double> q = new PriorityQueue<>(Collections.reverseOrder());
8997
for (int v : nums) {
9098
q.offer(v * 1.0);
9199
s += v;
92100
}
93-
double d = s / 2.0;
101+
s /= 2.0;
94102
int ans = 0;
95-
while (d > 0) {
103+
while (s > 0) {
96104
double t = q.poll();
97-
d -= t / 2.0;
105+
s -= t / 2.0;
98106
q.offer(t / 2.0);
99107
++ans;
100108
}
@@ -110,17 +118,17 @@ class Solution {
110118
public:
111119
int halveArray(vector<int>& nums) {
112120
priority_queue<double> q;
113-
long long s = 0;
121+
double s = 0;
114122
for (int& v : nums) {
115123
s += v;
116124
q.push(v);
117125
}
118-
double d = s / 2.0;
126+
s /= 2.0;
119127
int ans = 0;
120-
while (d > 0) {
128+
while (s > 0) {
121129
double t = q.top() / 2;
122130
q.pop();
123-
d -= t;
131+
s -= t;
124132
q.push(t);
125133
++ans;
126134
}
@@ -131,6 +139,36 @@ public:
131139
132140
### **Go**
133141
142+
```go
143+
func halveArray(nums []int) (ans int) {
144+
var s float64
145+
q := hp{}
146+
for _, x := range nums {
147+
s += float64(x)
148+
heap.Push(&q, float64(x))
149+
}
150+
s /= 2
151+
for s > 0 {
152+
x := heap.Pop(&q).(float64)
153+
ans++
154+
s -= x / 2
155+
heap.Push(&q, x/2)
156+
}
157+
return
158+
}
159+
160+
type hp struct{ sort.Float64Slice }
161+
162+
func (h hp) Less(i, j int) bool { return h.Float64Slice[i] > h.Float64Slice[j] }
163+
func (h *hp) Push(v interface{}) { h.Float64Slice = append(h.Float64Slice, v.(float64)) }
164+
func (h *hp) Pop() interface{} {
165+
a := h.Float64Slice
166+
v := a[len(a)-1]
167+
h.Float64Slice = a[:len(a)-1]
168+
return v
169+
}
170+
```
171+
134172
```go
135173
func halveArray(nums []int) (ans int) {
136174
half := 0

solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README_EN.md

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,17 @@ class Solution:
7676
```java
7777
class Solution {
7878
public int halveArray(int[] nums) {
79-
long s = 0;
79+
double s = 0;
8080
PriorityQueue<Double> q = new PriorityQueue<>(Collections.reverseOrder());
8181
for (int v : nums) {
8282
q.offer(v * 1.0);
8383
s += v;
8484
}
85-
double d = s / 2.0;
85+
s /= 2.0;
8686
int ans = 0;
87-
while (d > 0) {
87+
while (s > 0) {
8888
double t = q.poll();
89-
d -= t / 2.0;
89+
s -= t / 2.0;
9090
q.offer(t / 2.0);
9191
++ans;
9292
}
@@ -102,17 +102,17 @@ class Solution {
102102
public:
103103
int halveArray(vector<int>& nums) {
104104
priority_queue<double> q;
105-
long long s = 0;
105+
double s = 0;
106106
for (int& v : nums) {
107107
s += v;
108108
q.push(v);
109109
}
110-
double d = s / 2.0;
110+
s /= 2.0;
111111
int ans = 0;
112-
while (d > 0) {
112+
while (s > 0) {
113113
double t = q.top() / 2;
114114
q.pop();
115-
d -= t;
115+
s -= t;
116116
q.push(t);
117117
++ans;
118118
}
@@ -123,6 +123,36 @@ public:
123123
124124
### **Go**
125125
126+
```go
127+
func halveArray(nums []int) (ans int) {
128+
var s float64
129+
q := hp{}
130+
for _, x := range nums {
131+
s += float64(x)
132+
heap.Push(&q, float64(x))
133+
}
134+
s /= 2
135+
for s > 0 {
136+
x := heap.Pop(&q).(float64)
137+
ans++
138+
s -= x / 2
139+
heap.Push(&q, x/2)
140+
}
141+
return
142+
}
143+
144+
type hp struct{ sort.Float64Slice }
145+
146+
func (h hp) Less(i, j int) bool { return h.Float64Slice[i] > h.Float64Slice[j] }
147+
func (h *hp) Push(v interface{}) { h.Float64Slice = append(h.Float64Slice, v.(float64)) }
148+
func (h *hp) Pop() interface{} {
149+
a := h.Float64Slice
150+
v := a[len(a)-1]
151+
h.Float64Slice = a[:len(a)-1]
152+
return v
153+
}
154+
```
155+
126156
```go
127157
func halveArray(nums []int) (ans int) {
128158
half := 0
Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
class Solution {
2-
public:
3-
int halveArray(vector<int>& nums) {
4-
priority_queue<double> q;
5-
long long s = 0;
6-
for (int& v : nums) {
7-
s += v;
8-
q.push(v);
9-
}
10-
double d = s / 2.0;
11-
int ans = 0;
12-
while (d > 0) {
13-
double t = q.top() / 2;
14-
q.pop();
15-
d -= t;
16-
q.push(t);
17-
++ans;
18-
}
19-
return ans;
20-
}
1+
class Solution {
2+
public:
3+
int halveArray(vector<int>& nums) {
4+
priority_queue<double> q;
5+
double s = 0;
6+
for (int& v : nums) {
7+
s += v;
8+
q.push(v);
9+
}
10+
s /= 2.0;
11+
int ans = 0;
12+
while (s > 0) {
13+
double t = q.top() / 2;
14+
q.pop();
15+
s -= t;
16+
q.push(t);
17+
++ans;
18+
}
19+
return ans;
20+
}
2121
};
Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
func halveArray(nums []int) (ans int) {
2-
half := 0
3-
for i := range nums {
4-
nums[i] <<= 20
5-
half += nums[i]
2+
var s float64
3+
q := hp{}
4+
for _, x := range nums {
5+
s += float64(x)
6+
heap.Push(&q, float64(x))
67
}
7-
h := hp{nums}
8-
heap.Init(&h)
9-
for half >>= 1; half > 0; ans++ {
10-
half -= h.IntSlice[0] >> 1
11-
h.IntSlice[0] >>= 1
12-
heap.Fix(&h, 0)
8+
s /= 2
9+
for s > 0 {
10+
x := heap.Pop(&q).(float64)
11+
ans++
12+
s -= x / 2
13+
heap.Push(&q, x/2)
1314
}
1415
return
1516
}
1617

17-
type hp struct{ sort.IntSlice }
18+
type hp struct{ sort.Float64Slice }
1819

19-
func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }
20-
func (hp) Push(interface{}) {}
21-
func (hp) Pop() (_ interface{}) { return }
20+
func (h hp) Less(i, j int) bool { return h.Float64Slice[i] > h.Float64Slice[j] }
21+
func (h *hp) Push(v interface{}) { h.Float64Slice = append(h.Float64Slice, v.(float64)) }
22+
func (h *hp) Pop() interface{} {
23+
a := h.Float64Slice
24+
v := a[len(a)-1]
25+
h.Float64Slice = a[:len(a)-1]
26+
return v
27+
}
Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
class Solution {
2-
public int halveArray(int[] nums) {
3-
long s = 0;
4-
PriorityQueue<Double> q = new PriorityQueue<>(Collections.reverseOrder());
5-
for (int v : nums) {
6-
q.offer(v * 1.0);
7-
s += v;
8-
}
9-
double d = s / 2.0;
10-
int ans = 0;
11-
while (d > 0) {
12-
double t = q.poll();
13-
d -= t / 2.0;
14-
q.offer(t / 2.0);
15-
++ans;
16-
}
17-
return ans;
18-
}
1+
class Solution {
2+
public int halveArray(int[] nums) {
3+
double s = 0;
4+
PriorityQueue<Double> q = new PriorityQueue<>(Collections.reverseOrder());
5+
for (int v : nums) {
6+
q.offer(v * 1.0);
7+
s += v;
8+
}
9+
s /= 2.0;
10+
int ans = 0;
11+
while (s > 0) {
12+
double t = q.poll();
13+
s -= t / 2.0;
14+
q.offer(t / 2.0);
15+
++ans;
16+
}
17+
return ans;
18+
}
1919
}

0 commit comments

Comments
 (0)