Skip to content

Commit 3d8a308

Browse files
authored
feat: add solutions to lc problem: No.1962 (doocs#2144)
No.1962.Remove Stones to Minimize the Total
1 parent 2f8ef10 commit 3d8a308

File tree

7 files changed

+189
-118
lines changed

7 files changed

+189
-118
lines changed

solution/1900-1999/1962.Remove Stones to Minimize the Total/README.md

+61-33
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,17 @@
5757

5858
<!-- 这里可写通用的实现逻辑 -->
5959

60-
**方法一:优先队列(大根堆)**
60+
**方法一:贪心 + 优先队列(大根堆)**
61+
62+
根据题目描述,为了使得剩下的石子总数最小,我们需要尽可能多地移除石子堆中的石子。因此,每次应该选择数量最多的石子堆进行移除。
63+
64+
我们创建一个优先队列(大根堆) $pq$,用于存储石子堆的数量。初始时,将所有石子堆的数量加入优先队列。
65+
66+
接下来,我们进行 $k$ 次操作。在每一次操作中,我们取出优先队列的堆顶元素 $x$,将 $x$ 减半后重新加入优先队列。
67+
68+
在进行了 $k$ 次操作后,优先队列中所有元素的和即为答案。
69+
70+
时间复杂度 $O(n + k \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 `piles` 的长度。
6171

6272
<!-- tabs:start -->
6373

@@ -68,13 +78,11 @@
6878
```python
6979
class Solution:
7080
def minStoneSum(self, piles: List[int], k: int) -> int:
71-
h = []
72-
for p in piles:
73-
heappush(h, -p)
81+
pq = [-x for x in piles]
82+
heapify(pq)
7483
for _ in range(k):
75-
p = -heappop(h)
76-
heappush(h, -((p + 1) >> 1))
77-
return -sum(h)
84+
heapreplace(pq, pq[0] // 2)
85+
return -sum(pq)
7886
```
7987

8088
### **Java**
@@ -84,17 +92,17 @@ class Solution:
8492
```java
8593
class Solution {
8694
public int minStoneSum(int[] piles, int k) {
87-
PriorityQueue<Integer> q = new PriorityQueue<>((a, b) -> (b - a));
88-
for (int p : piles) {
89-
q.offer(p);
95+
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
96+
for (int x : piles) {
97+
pq.offer(x);
9098
}
9199
while (k-- > 0) {
92-
int p = q.poll();
93-
q.offer((p + 1) >> 1);
100+
int x = pq.poll();
101+
pq.offer(x - x / 2);
94102
}
95103
int ans = 0;
96-
while (!q.isEmpty()) {
97-
ans += q.poll();
104+
while (!pq.isEmpty()) {
105+
ans += pq.poll();
98106
}
99107
return ans;
100108
}
@@ -107,17 +115,19 @@ class Solution {
107115
class Solution {
108116
public:
109117
int minStoneSum(vector<int>& piles, int k) {
110-
priority_queue<int> q;
111-
for (int& p : piles) q.push(p);
118+
priority_queue<int> pq;
119+
for (int x : piles) {
120+
pq.push(x);
121+
}
112122
while (k--) {
113-
int p = q.top();
114-
q.pop();
115-
q.push((p + 1) >> 1);
123+
int x = pq.top();
124+
pq.pop();
125+
pq.push(x - x / 2);
116126
}
117127
int ans = 0;
118-
while (!q.empty()) {
119-
ans += q.top();
120-
q.pop();
128+
while (!pq.empty()) {
129+
ans += pq.top();
130+
pq.pop();
121131
}
122132
return ans;
123133
}
@@ -127,19 +137,17 @@ public:
127137
### **Go**
128138
129139
```go
130-
func minStoneSum(piles []int, k int) int {
131-
q := &hp{piles}
132-
heap.Init(q)
133-
for k > 0 {
134-
p := q.pop()
135-
q.push((p + 1) >> 1)
136-
k--
140+
func minStoneSum(piles []int, k int) (ans int) {
141+
pq := &hp{piles}
142+
heap.Init(pq)
143+
for ; k > 0; k-- {
144+
x := pq.pop()
145+
pq.push(x - x/2)
137146
}
138-
ans := 0
139-
for q.Len() > 0 {
140-
ans += q.pop()
147+
for pq.Len() > 0 {
148+
ans += pq.pop()
141149
}
142-
return ans
150+
return
143151
}
144152
145153
type hp struct{ sort.IntSlice }
@@ -156,6 +164,26 @@ func (h *hp) push(v int) { heap.Push(h, v) }
156164
func (h *hp) pop() int { return heap.Pop(h).(int) }
157165
```
158166

167+
### **TypeScript**
168+
169+
```ts
170+
function minStoneSum(piles: number[], k: number): number {
171+
const pq = new MaxPriorityQueue();
172+
for (const x of piles) {
173+
pq.enqueue(x);
174+
}
175+
while (k--) {
176+
const x = pq.dequeue().element;
177+
pq.enqueue(x - ((x / 2) | 0));
178+
}
179+
let ans = 0;
180+
while (pq.size()) {
181+
ans += pq.dequeue().element;
182+
}
183+
return ans;
184+
}
185+
```
186+
159187
### **...**
160188

161189
```

solution/1900-1999/1962.Remove Stones to Minimize the Total/README_EN.md

+62-32
Original file line numberDiff line numberDiff line change
@@ -51,38 +51,48 @@ The total number of stones in [2,3,3,4] is 12.
5151

5252
## Solutions
5353

54+
**Solution 1: Greedy + Priority Queue (Max Heap)**
55+
56+
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.
57+
58+
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.
59+
60+
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.
61+
62+
After performing $k$ operations, the sum of all elements in the priority queue is the answer.
63+
64+
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`.
65+
5466
<!-- tabs:start -->
5567

5668
### **Python3**
5769

5870
```python
5971
class Solution:
6072
def minStoneSum(self, piles: List[int], k: int) -> int:
61-
h = []
62-
for p in piles:
63-
heappush(h, -p)
73+
pq = [-x for x in piles]
74+
heapify(pq)
6475
for _ in range(k):
65-
p = -heappop(h)
66-
heappush(h, -((p + 1) >> 1))
67-
return -sum(h)
76+
heapreplace(pq, pq[0] // 2)
77+
return -sum(pq)
6878
```
6979

7080
### **Java**
7181

7282
```java
7383
class Solution {
7484
public int minStoneSum(int[] piles, int k) {
75-
PriorityQueue<Integer> q = new PriorityQueue<>((a, b) -> (b - a));
76-
for (int p : piles) {
77-
q.offer(p);
85+
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
86+
for (int x : piles) {
87+
pq.offer(x);
7888
}
7989
while (k-- > 0) {
80-
int p = q.poll();
81-
q.offer((p + 1) >> 1);
90+
int x = pq.poll();
91+
pq.offer(x - x / 2);
8292
}
8393
int ans = 0;
84-
while (!q.isEmpty()) {
85-
ans += q.poll();
94+
while (!pq.isEmpty()) {
95+
ans += pq.poll();
8696
}
8797
return ans;
8898
}
@@ -95,17 +105,19 @@ class Solution {
95105
class Solution {
96106
public:
97107
int minStoneSum(vector<int>& piles, int k) {
98-
priority_queue<int> q;
99-
for (int& p : piles) q.push(p);
108+
priority_queue<int> pq;
109+
for (int x : piles) {
110+
pq.push(x);
111+
}
100112
while (k--) {
101-
int p = q.top();
102-
q.pop();
103-
q.push((p + 1) >> 1);
113+
int x = pq.top();
114+
pq.pop();
115+
pq.push(x - x / 2);
104116
}
105117
int ans = 0;
106-
while (!q.empty()) {
107-
ans += q.top();
108-
q.pop();
118+
while (!pq.empty()) {
119+
ans += pq.top();
120+
pq.pop();
109121
}
110122
return ans;
111123
}
@@ -115,19 +127,17 @@ public:
115127
### **Go**
116128
117129
```go
118-
func minStoneSum(piles []int, k int) int {
119-
q := &hp{piles}
120-
heap.Init(q)
121-
for k > 0 {
122-
p := q.pop()
123-
q.push((p + 1) >> 1)
124-
k--
130+
func minStoneSum(piles []int, k int) (ans int) {
131+
pq := &hp{piles}
132+
heap.Init(pq)
133+
for ; k > 0; k-- {
134+
x := pq.pop()
135+
pq.push(x - x/2)
125136
}
126-
ans := 0
127-
for q.Len() > 0 {
128-
ans += q.pop()
137+
for pq.Len() > 0 {
138+
ans += pq.pop()
129139
}
130-
return ans
140+
return
131141
}
132142
133143
type hp struct{ sort.IntSlice }
@@ -144,6 +154,26 @@ func (h *hp) push(v int) { heap.Push(h, v) }
144154
func (h *hp) pop() int { return heap.Pop(h).(int) }
145155
```
146156

157+
### **TypeScript**
158+
159+
```ts
160+
function minStoneSum(piles: number[], k: number): number {
161+
const pq = new MaxPriorityQueue();
162+
for (const x of piles) {
163+
pq.enqueue(x);
164+
}
165+
while (k--) {
166+
const x = pq.dequeue().element;
167+
pq.enqueue(x - ((x / 2) | 0));
168+
}
169+
let ans = 0;
170+
while (pq.size()) {
171+
ans += pq.dequeue().element;
172+
}
173+
return ans;
174+
}
175+
```
176+
147177
### **...**
148178

149179
```
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
class Solution {
2-
public:
3-
int minStoneSum(vector<int>& piles, int k) {
4-
priority_queue<int> q;
5-
for (int& p : piles) q.push(p);
6-
while (k--) {
7-
int p = q.top();
8-
q.pop();
9-
q.push((p + 1) >> 1);
10-
}
11-
int ans = 0;
12-
while (!q.empty()) {
13-
ans += q.top();
14-
q.pop();
15-
}
16-
return ans;
17-
}
1+
class Solution {
2+
public:
3+
int minStoneSum(vector<int>& piles, int k) {
4+
priority_queue<int> pq;
5+
for (int x : piles) {
6+
pq.push(x);
7+
}
8+
while (k--) {
9+
int x = pq.top();
10+
pq.pop();
11+
pq.push(x - x / 2);
12+
}
13+
int ans = 0;
14+
while (!pq.empty()) {
15+
ans += pq.top();
16+
pq.pop();
17+
}
18+
return ans;
19+
}
1820
};

solution/1900-1999/1962.Remove Stones to Minimize the Total/Solution.go

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
func minStoneSum(piles []int, k int) int {
2-
q := &hp{piles}
3-
heap.Init(q)
4-
for k > 0 {
5-
p := q.pop()
6-
q.push((p + 1) >> 1)
7-
k--
1+
func minStoneSum(piles []int, k int) (ans int) {
2+
pq := &hp{piles}
3+
heap.Init(pq)
4+
for ; k > 0; k-- {
5+
x := pq.pop()
6+
pq.push(x - x/2)
87
}
9-
ans := 0
10-
for q.Len() > 0 {
11-
ans += q.pop()
8+
for pq.Len() > 0 {
9+
ans += pq.pop()
1210
}
13-
return ans
11+
return
1412
}
1513

1614
type hp struct{ sort.IntSlice }
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
class Solution {
2-
public int minStoneSum(int[] piles, int k) {
3-
PriorityQueue<Integer> q = new PriorityQueue<>((a, b) -> (b - a));
4-
for (int p : piles) {
5-
q.offer(p);
6-
}
7-
while (k-- > 0) {
8-
int p = q.poll();
9-
q.offer((p + 1) >> 1);
10-
}
11-
int ans = 0;
12-
while (!q.isEmpty()) {
13-
ans += q.poll();
14-
}
15-
return ans;
16-
}
1+
class Solution {
2+
public int minStoneSum(int[] piles, int k) {
3+
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
4+
for (int x : piles) {
5+
pq.offer(x);
6+
}
7+
while (k-- > 0) {
8+
int x = pq.poll();
9+
pq.offer(x - x / 2);
10+
}
11+
int ans = 0;
12+
while (!pq.isEmpty()) {
13+
ans += pq.poll();
14+
}
15+
return ans;
16+
}
1717
}

0 commit comments

Comments
 (0)