diff --git a/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README.md b/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README.md index 430f2b60153d3..f0e96c7c67184 100644 --- a/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README.md +++ b/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README.md @@ -55,6 +55,14 @@ nums 的和减小了 31 - 14.5 = 16.5 ,减小的部分超过了初始数组和 +**方法一:贪心 + 优先队列(大根堆)** + +根据题目描述,每一次操作,都会将数组中的一个数减半。要使得数组和至少减少一半的操作次数最少,那么每一次操作都应该选择当前数组中的最大值进行减半。 + +因此,我们先算出数组要减少的总和 $s$,然后用一个优先队列(大根堆)维护数组中的所有数,每次从优先队列中取出最大值 $t$,将其减半,然后将减半后的数重新放入优先队列中,同时更新 $s$,直到 $s \le 0$ 为止。那么此时的操作次数就是答案。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 + ### **Python3** @@ -84,17 +92,17 @@ class Solution: ```java class Solution { public int halveArray(int[] nums) { - long s = 0; + double s = 0; PriorityQueue q = new PriorityQueue<>(Collections.reverseOrder()); for (int v : nums) { q.offer(v * 1.0); s += v; } - double d = s / 2.0; + s /= 2.0; int ans = 0; - while (d > 0) { + while (s > 0) { double t = q.poll(); - d -= t / 2.0; + s -= t / 2.0; q.offer(t / 2.0); ++ans; } @@ -110,17 +118,17 @@ class Solution { public: int halveArray(vector& nums) { priority_queue q; - long long s = 0; + double s = 0; for (int& v : nums) { s += v; q.push(v); } - double d = s / 2.0; + s /= 2.0; int ans = 0; - while (d > 0) { + while (s > 0) { double t = q.top() / 2; q.pop(); - d -= t; + s -= t; q.push(t); ++ans; } @@ -131,6 +139,36 @@ public: ### **Go** +```go +func halveArray(nums []int) (ans int) { + var s float64 + q := hp{} + for _, x := range nums { + s += float64(x) + heap.Push(&q, float64(x)) + } + s /= 2 + for s > 0 { + x := heap.Pop(&q).(float64) + ans++ + s -= x / 2 + heap.Push(&q, x/2) + } + return +} + +type hp struct{ sort.Float64Slice } + +func (h hp) Less(i, j int) bool { return h.Float64Slice[i] > h.Float64Slice[j] } +func (h *hp) Push(v interface{}) { h.Float64Slice = append(h.Float64Slice, v.(float64)) } +func (h *hp) Pop() interface{} { + a := h.Float64Slice + v := a[len(a)-1] + h.Float64Slice = a[:len(a)-1] + return v +} +``` + ```go func halveArray(nums []int) (ans int) { half := 0 diff --git a/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README_EN.md b/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README_EN.md index f0430277b1a8b..337a6099377e5 100644 --- a/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README_EN.md +++ b/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README_EN.md @@ -76,17 +76,17 @@ class Solution: ```java class Solution { public int halveArray(int[] nums) { - long s = 0; + double s = 0; PriorityQueue q = new PriorityQueue<>(Collections.reverseOrder()); for (int v : nums) { q.offer(v * 1.0); s += v; } - double d = s / 2.0; + s /= 2.0; int ans = 0; - while (d > 0) { + while (s > 0) { double t = q.poll(); - d -= t / 2.0; + s -= t / 2.0; q.offer(t / 2.0); ++ans; } @@ -102,17 +102,17 @@ class Solution { public: int halveArray(vector& nums) { priority_queue q; - long long s = 0; + double s = 0; for (int& v : nums) { s += v; q.push(v); } - double d = s / 2.0; + s /= 2.0; int ans = 0; - while (d > 0) { + while (s > 0) { double t = q.top() / 2; q.pop(); - d -= t; + s -= t; q.push(t); ++ans; } @@ -123,6 +123,36 @@ public: ### **Go** +```go +func halveArray(nums []int) (ans int) { + var s float64 + q := hp{} + for _, x := range nums { + s += float64(x) + heap.Push(&q, float64(x)) + } + s /= 2 + for s > 0 { + x := heap.Pop(&q).(float64) + ans++ + s -= x / 2 + heap.Push(&q, x/2) + } + return +} + +type hp struct{ sort.Float64Slice } + +func (h hp) Less(i, j int) bool { return h.Float64Slice[i] > h.Float64Slice[j] } +func (h *hp) Push(v interface{}) { h.Float64Slice = append(h.Float64Slice, v.(float64)) } +func (h *hp) Pop() interface{} { + a := h.Float64Slice + v := a[len(a)-1] + h.Float64Slice = a[:len(a)-1] + return v +} +``` + ```go func halveArray(nums []int) (ans int) { half := 0 diff --git a/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.cpp b/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.cpp index cc37499ef12de..f385ff5be5a6b 100644 --- a/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.cpp +++ b/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.cpp @@ -1,21 +1,21 @@ -class Solution { -public: - int halveArray(vector& nums) { - priority_queue q; - long long s = 0; - for (int& v : nums) { - s += v; - q.push(v); - } - double d = s / 2.0; - int ans = 0; - while (d > 0) { - double t = q.top() / 2; - q.pop(); - d -= t; - q.push(t); - ++ans; - } - return ans; - } +class Solution { +public: + int halveArray(vector& nums) { + priority_queue q; + double s = 0; + for (int& v : nums) { + s += v; + q.push(v); + } + s /= 2.0; + int ans = 0; + while (s > 0) { + double t = q.top() / 2; + q.pop(); + s -= t; + q.push(t); + ++ans; + } + return ans; + } }; \ No newline at end of file diff --git a/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.go b/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.go index 4c9d8623dc540..d948eda08d4c1 100644 --- a/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.go +++ b/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.go @@ -1,21 +1,27 @@ func halveArray(nums []int) (ans int) { - half := 0 - for i := range nums { - nums[i] <<= 20 - half += nums[i] + var s float64 + q := hp{} + for _, x := range nums { + s += float64(x) + heap.Push(&q, float64(x)) } - h := hp{nums} - heap.Init(&h) - for half >>= 1; half > 0; ans++ { - half -= h.IntSlice[0] >> 1 - h.IntSlice[0] >>= 1 - heap.Fix(&h, 0) + s /= 2 + for s > 0 { + x := heap.Pop(&q).(float64) + ans++ + s -= x / 2 + heap.Push(&q, x/2) } return } -type hp struct{ sort.IntSlice } +type hp struct{ sort.Float64Slice } -func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] } -func (hp) Push(interface{}) {} -func (hp) Pop() (_ interface{}) { return } \ No newline at end of file +func (h hp) Less(i, j int) bool { return h.Float64Slice[i] > h.Float64Slice[j] } +func (h *hp) Push(v interface{}) { h.Float64Slice = append(h.Float64Slice, v.(float64)) } +func (h *hp) Pop() interface{} { + a := h.Float64Slice + v := a[len(a)-1] + h.Float64Slice = a[:len(a)-1] + return v +} \ No newline at end of file diff --git a/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.java b/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.java index 78c4fd59ae59c..07ef802ff10c5 100644 --- a/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.java +++ b/solution/2200-2299/2208.Minimum Operations to Halve Array Sum/Solution.java @@ -1,19 +1,19 @@ -class Solution { - public int halveArray(int[] nums) { - long s = 0; - PriorityQueue q = new PriorityQueue<>(Collections.reverseOrder()); - for (int v : nums) { - q.offer(v * 1.0); - s += v; - } - double d = s / 2.0; - int ans = 0; - while (d > 0) { - double t = q.poll(); - d -= t / 2.0; - q.offer(t / 2.0); - ++ans; - } - return ans; - } +class Solution { + public int halveArray(int[] nums) { + double s = 0; + PriorityQueue q = new PriorityQueue<>(Collections.reverseOrder()); + for (int v : nums) { + q.offer(v * 1.0); + s += v; + } + s /= 2.0; + int ans = 0; + while (s > 0) { + double t = q.poll(); + s -= t / 2.0; + q.offer(t / 2.0); + ++ans; + } + return ans; + } } \ No newline at end of file