diff --git a/solution/1900-1999/1962.Remove Stones to Minimize the Total/README.md b/solution/1900-1999/1962.Remove Stones to Minimize the Total/README.md index 1e8817d75e9db..4af062eb390c5 100644 --- a/solution/1900-1999/1962.Remove Stones to Minimize the Total/README.md +++ b/solution/1900-1999/1962.Remove Stones to Minimize the Total/README.md @@ -57,7 +57,17 @@ -**方法一:优先队列(大根堆)** +**方法一:贪心 + 优先队列(大根堆)** + +根据题目描述,为了使得剩下的石子总数最小,我们需要尽可能多地移除石子堆中的石子。因此,每次应该选择数量最多的石子堆进行移除。 + +我们创建一个优先队列(大根堆) $pq$,用于存储石子堆的数量。初始时,将所有石子堆的数量加入优先队列。 + +接下来,我们进行 $k$ 次操作。在每一次操作中,我们取出优先队列的堆顶元素 $x$,将 $x$ 减半后重新加入优先队列。 + +在进行了 $k$ 次操作后,优先队列中所有元素的和即为答案。 + +时间复杂度 $O(n + k \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 `piles` 的长度。 @@ -68,13 +78,11 @@ ```python class Solution: def minStoneSum(self, piles: List[int], k: int) -> int: - h = [] - for p in piles: - heappush(h, -p) + pq = [-x for x in piles] + heapify(pq) for _ in range(k): - p = -heappop(h) - heappush(h, -((p + 1) >> 1)) - return -sum(h) + heapreplace(pq, pq[0] // 2) + return -sum(pq) ``` ### **Java** @@ -84,17 +92,17 @@ class Solution: ```java class Solution { public int minStoneSum(int[] piles, int k) { - PriorityQueue q = new PriorityQueue<>((a, b) -> (b - a)); - for (int p : piles) { - q.offer(p); + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + for (int x : piles) { + pq.offer(x); } while (k-- > 0) { - int p = q.poll(); - q.offer((p + 1) >> 1); + int x = pq.poll(); + pq.offer(x - x / 2); } int ans = 0; - while (!q.isEmpty()) { - ans += q.poll(); + while (!pq.isEmpty()) { + ans += pq.poll(); } return ans; } @@ -107,17 +115,19 @@ class Solution { class Solution { public: int minStoneSum(vector& piles, int k) { - priority_queue q; - for (int& p : piles) q.push(p); + priority_queue pq; + for (int x : piles) { + pq.push(x); + } while (k--) { - int p = q.top(); - q.pop(); - q.push((p + 1) >> 1); + int x = pq.top(); + pq.pop(); + pq.push(x - x / 2); } int ans = 0; - while (!q.empty()) { - ans += q.top(); - q.pop(); + while (!pq.empty()) { + ans += pq.top(); + pq.pop(); } return ans; } @@ -127,19 +137,17 @@ public: ### **Go** ```go -func minStoneSum(piles []int, k int) int { - q := &hp{piles} - heap.Init(q) - for k > 0 { - p := q.pop() - q.push((p + 1) >> 1) - k-- +func minStoneSum(piles []int, k int) (ans int) { + pq := &hp{piles} + heap.Init(pq) + for ; k > 0; k-- { + x := pq.pop() + pq.push(x - x/2) } - ans := 0 - for q.Len() > 0 { - ans += q.pop() + for pq.Len() > 0 { + ans += pq.pop() } - return ans + return } type hp struct{ sort.IntSlice } @@ -156,6 +164,26 @@ func (h *hp) push(v int) { heap.Push(h, v) } func (h *hp) pop() int { return heap.Pop(h).(int) } ``` +### **TypeScript** + +```ts +function minStoneSum(piles: number[], k: number): number { + const pq = new MaxPriorityQueue(); + for (const x of piles) { + pq.enqueue(x); + } + while (k--) { + const x = pq.dequeue().element; + pq.enqueue(x - ((x / 2) | 0)); + } + let ans = 0; + while (pq.size()) { + ans += pq.dequeue().element; + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/1900-1999/1962.Remove Stones to Minimize the Total/README_EN.md b/solution/1900-1999/1962.Remove Stones to Minimize the Total/README_EN.md index b9b1037c7b5a5..be8a372b5f73a 100644 --- a/solution/1900-1999/1962.Remove Stones to Minimize the Total/README_EN.md +++ b/solution/1900-1999/1962.Remove Stones to Minimize the Total/README_EN.md @@ -51,6 +51,18 @@ The total number of stones in [2,3,3,4] is 12. ## Solutions +**Solution 1: Greedy + Priority Queue (Max Heap)** + +According to the problem description, in order to minimize the total number of remaining stones, we need to remove as many stones as possible from the stone piles. Therefore, we should always choose the pile with the most stones for removal. + +We create a priority queue (max heap) $pq$ to store the number of stones in each pile. Initially, we add the number of stones in all piles to the priority queue. + +Next, we perform $k$ operations. In each operation, we take out the top element $x$ of the priority queue, halve $x$, and then add it back to the priority queue. + +After performing $k$ operations, the sum of all elements in the priority queue is the answer. + +The time complexity is $O(n + k \times \log n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array `piles`. + ### **Python3** @@ -58,13 +70,11 @@ The total number of stones in [2,3,3,4] is 12. ```python class Solution: def minStoneSum(self, piles: List[int], k: int) -> int: - h = [] - for p in piles: - heappush(h, -p) + pq = [-x for x in piles] + heapify(pq) for _ in range(k): - p = -heappop(h) - heappush(h, -((p + 1) >> 1)) - return -sum(h) + heapreplace(pq, pq[0] // 2) + return -sum(pq) ``` ### **Java** @@ -72,17 +82,17 @@ class Solution: ```java class Solution { public int minStoneSum(int[] piles, int k) { - PriorityQueue q = new PriorityQueue<>((a, b) -> (b - a)); - for (int p : piles) { - q.offer(p); + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + for (int x : piles) { + pq.offer(x); } while (k-- > 0) { - int p = q.poll(); - q.offer((p + 1) >> 1); + int x = pq.poll(); + pq.offer(x - x / 2); } int ans = 0; - while (!q.isEmpty()) { - ans += q.poll(); + while (!pq.isEmpty()) { + ans += pq.poll(); } return ans; } @@ -95,17 +105,19 @@ class Solution { class Solution { public: int minStoneSum(vector& piles, int k) { - priority_queue q; - for (int& p : piles) q.push(p); + priority_queue pq; + for (int x : piles) { + pq.push(x); + } while (k--) { - int p = q.top(); - q.pop(); - q.push((p + 1) >> 1); + int x = pq.top(); + pq.pop(); + pq.push(x - x / 2); } int ans = 0; - while (!q.empty()) { - ans += q.top(); - q.pop(); + while (!pq.empty()) { + ans += pq.top(); + pq.pop(); } return ans; } @@ -115,19 +127,17 @@ public: ### **Go** ```go -func minStoneSum(piles []int, k int) int { - q := &hp{piles} - heap.Init(q) - for k > 0 { - p := q.pop() - q.push((p + 1) >> 1) - k-- +func minStoneSum(piles []int, k int) (ans int) { + pq := &hp{piles} + heap.Init(pq) + for ; k > 0; k-- { + x := pq.pop() + pq.push(x - x/2) } - ans := 0 - for q.Len() > 0 { - ans += q.pop() + for pq.Len() > 0 { + ans += pq.pop() } - return ans + return } type hp struct{ sort.IntSlice } @@ -144,6 +154,26 @@ func (h *hp) push(v int) { heap.Push(h, v) } func (h *hp) pop() int { return heap.Pop(h).(int) } ``` +### **TypeScript** + +```ts +function minStoneSum(piles: number[], k: number): number { + const pq = new MaxPriorityQueue(); + for (const x of piles) { + pq.enqueue(x); + } + while (k--) { + const x = pq.dequeue().element; + pq.enqueue(x - ((x / 2) | 0)); + } + let ans = 0; + while (pq.size()) { + ans += pq.dequeue().element; + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.cpp b/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.cpp index a45fecd3a2219..eaa06dd347d95 100644 --- a/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.cpp +++ b/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.cpp @@ -1,18 +1,20 @@ -class Solution { -public: - int minStoneSum(vector& piles, int k) { - priority_queue q; - for (int& p : piles) q.push(p); - while (k--) { - int p = q.top(); - q.pop(); - q.push((p + 1) >> 1); - } - int ans = 0; - while (!q.empty()) { - ans += q.top(); - q.pop(); - } - return ans; - } +class Solution { +public: + int minStoneSum(vector& piles, int k) { + priority_queue pq; + for (int x : piles) { + pq.push(x); + } + while (k--) { + int x = pq.top(); + pq.pop(); + pq.push(x - x / 2); + } + int ans = 0; + while (!pq.empty()) { + ans += pq.top(); + pq.pop(); + } + return ans; + } }; \ No newline at end of file diff --git a/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.go b/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.go index a9caa8829fde3..5380bb0f77530 100644 --- a/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.go +++ b/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.go @@ -1,16 +1,14 @@ -func minStoneSum(piles []int, k int) int { - q := &hp{piles} - heap.Init(q) - for k > 0 { - p := q.pop() - q.push((p + 1) >> 1) - k-- +func minStoneSum(piles []int, k int) (ans int) { + pq := &hp{piles} + heap.Init(pq) + for ; k > 0; k-- { + x := pq.pop() + pq.push(x - x/2) } - ans := 0 - for q.Len() > 0 { - ans += q.pop() + for pq.Len() > 0 { + ans += pq.pop() } - return ans + return } type hp struct{ sort.IntSlice } diff --git a/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.java b/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.java index e18ceb6f50013..5d637cbb93631 100644 --- a/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.java +++ b/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.java @@ -1,17 +1,17 @@ -class Solution { - public int minStoneSum(int[] piles, int k) { - PriorityQueue q = new PriorityQueue<>((a, b) -> (b - a)); - for (int p : piles) { - q.offer(p); - } - while (k-- > 0) { - int p = q.poll(); - q.offer((p + 1) >> 1); - } - int ans = 0; - while (!q.isEmpty()) { - ans += q.poll(); - } - return ans; - } +class Solution { + public int minStoneSum(int[] piles, int k) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + for (int x : piles) { + pq.offer(x); + } + while (k-- > 0) { + int x = pq.poll(); + pq.offer(x - x / 2); + } + int ans = 0; + while (!pq.isEmpty()) { + ans += pq.poll(); + } + return ans; + } } \ No newline at end of file diff --git a/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.py b/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.py index 3f1695ab6f5d8..7cd34c576c9db 100644 --- a/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.py +++ b/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.py @@ -1,9 +1,7 @@ -class Solution: - def minStoneSum(self, piles: List[int], k: int) -> int: - h = [] - for p in piles: - heappush(h, -p) - for _ in range(k): - p = -heappop(h) - heappush(h, -((p + 1) >> 1)) - return -sum(h) +class Solution: + def minStoneSum(self, piles: List[int], k: int) -> int: + pq = [-x for x in piles] + heapify(pq) + for _ in range(k): + heapreplace(pq, pq[0] // 2) + return -sum(pq) diff --git a/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.ts b/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.ts new file mode 100644 index 0000000000000..764899a28b058 --- /dev/null +++ b/solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.ts @@ -0,0 +1,15 @@ +function minStoneSum(piles: number[], k: number): number { + const pq = new MaxPriorityQueue(); + for (const x of piles) { + pq.enqueue(x); + } + while (k--) { + const x = pq.dequeue().element; + pq.enqueue(x - ((x / 2) | 0)); + } + let ans = 0; + while (pq.size()) { + ans += pq.dequeue().element; + } + return ans; +}