Skip to content

Commit 4ea153a

Browse files
authored
feat: add solutions to lc problem: No.2163 (#1504)
No.2163.Minimum Difference in Sums After Removal of Elements
1 parent a12260e commit 4ea153a

File tree

10 files changed

+586
-7
lines changed

10 files changed

+586
-7
lines changed

solution/2100-2199/2163.Minimum Difference in Sums After Removal of Elements/README.md

+205-2
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,231 @@
6262

6363
<!-- 这里可写通用的实现逻辑 -->
6464

65+
**方法一:优先队列(大小根堆)+ 前后缀和 + 枚举分割点**
66+
67+
题目实际上等价于在 $nums$ 中找到一个分割点,将数组分成左右两部分,在前一部分中选取最小的 $n$ 个元素,在后一部分中选取最大的 $n$ 个元素,使得两部分和的差值最小。
68+
69+
我们可以用一个大根堆维护前缀中最小的 $n$ 个元素,用一个小根堆维护后缀中最大的 $n$ 个元素。我们定义 $pre[i]$ 表示在数组 $nums$ 的前 $i$ 个元素中选择最小的 $n$ 个元素的和,定义 $suf[i]$ 表示从数组第 $i$ 个元素到最后一个元素中选择最大的 $n$ 个元素的和。在维护大小根堆的过程中,更新 $pre[i]$ 和 $suf[i]$ 的值。
70+
71+
最后,我们在 $i \in [n, 2n]$ 的范围内枚举分割点,计算 $pre[i] - suf[i + 1]$ 的值,取最小值即可。
72+
73+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
74+
6575
<!-- tabs:start -->
6676

6777
### **Python3**
6878

6979
<!-- 这里可写当前语言的特殊实现逻辑 -->
7080

7181
```python
72-
82+
class Solution:
83+
def minimumDifference(self, nums: List[int]) -> int:
84+
m = len(nums)
85+
n = m // 3
86+
87+
s = 0
88+
pre = [0] * (m + 1)
89+
q1 = []
90+
for i, x in enumerate(nums[: n * 2], 1):
91+
s += x
92+
heappush(q1, -x)
93+
if len(q1) > n:
94+
s -= -heappop(q1)
95+
pre[i] = s
96+
97+
s = 0
98+
suf = [0] * (m + 1)
99+
q2 = []
100+
for i in range(m, n, -1):
101+
x = nums[i - 1]
102+
s += x
103+
heappush(q2, x)
104+
if len(q2) > n:
105+
s -= heappop(q2)
106+
suf[i] = s
107+
108+
return min(pre[i] - suf[i + 1] for i in range(n, n * 2 + 1))
73109
```
74110

75111
### **Java**
76112

77113
<!-- 这里可写当前语言的特殊实现逻辑 -->
78114

79115
```java
116+
class Solution {
117+
public long minimumDifference(int[] nums) {
118+
int m = nums.length;
119+
int n = m / 3;
120+
long s = 0;
121+
long[] pre = new long[m + 1];
122+
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
123+
for (int i = 1; i <= n * 2; ++i) {
124+
int x = nums[i - 1];
125+
s += x;
126+
pq.offer(x);
127+
if (pq.size() > n) {
128+
s -= pq.poll();
129+
}
130+
pre[i] = s;
131+
}
132+
s = 0;
133+
long[] suf = new long[m + 1];
134+
pq = new PriorityQueue<>();
135+
for (int i = m; i > n; --i) {
136+
int x = nums[i - 1];
137+
s += x;
138+
pq.offer(x);
139+
if (pq.size() > n) {
140+
s -= pq.poll();
141+
}
142+
suf[i] = s;
143+
}
144+
long ans = 1L << 60;
145+
for (int i = n; i <= n * 2; ++i) {
146+
ans = Math.min(ans, pre[i] - suf[i + 1]);
147+
}
148+
return ans;
149+
}
150+
}
151+
```
80152

153+
### **C++**
154+
155+
```cpp
156+
class Solution {
157+
public:
158+
long long minimumDifference(vector<int>& nums) {
159+
int m = nums.size();
160+
int n = m / 3;
161+
162+
using ll = long long;
163+
ll s = 0;
164+
ll pre[m + 1];
165+
priority_queue<int> q1;
166+
for (int i = 1; i <= n * 2; ++i) {
167+
int x = nums[i - 1];
168+
s += x;
169+
q1.push(x);
170+
if (q1.size() > n) {
171+
s -= q1.top();
172+
q1.pop();
173+
}
174+
pre[i] = s;
175+
}
176+
s = 0;
177+
ll suf[m + 1];
178+
priority_queue<int, vector<int>, greater<int>> q2;
179+
for (int i = m; i > n; --i) {
180+
int x = nums[i - 1];
181+
s += x;
182+
q2.push(x);
183+
if (q2.size() > n) {
184+
s -= q2.top();
185+
q2.pop();
186+
}
187+
suf[i] = s;
188+
}
189+
ll ans = 1e18;
190+
for (int i = n; i <= n * 2; ++i) {
191+
ans = min(ans, pre[i] - suf[i + 1]);
192+
}
193+
return ans;
194+
}
195+
};
196+
```
197+
198+
### **Go**
199+
200+
```go
201+
func minimumDifference(nums []int) int64 {
202+
m := len(nums)
203+
n := m / 3
204+
s := 0
205+
pre := make([]int, m+1)
206+
q1 := hp{}
207+
for i := 1; i <= n*2; i++ {
208+
x := nums[i-1]
209+
s += x
210+
heap.Push(&q1, -x)
211+
if q1.Len() > n {
212+
s -= -heap.Pop(&q1).(int)
213+
}
214+
pre[i] = s
215+
}
216+
s = 0
217+
suf := make([]int, m+1)
218+
q2 := hp{}
219+
for i := m; i > n; i-- {
220+
x := nums[i-1]
221+
s += x
222+
heap.Push(&q2, x)
223+
if q2.Len() > n {
224+
s -= heap.Pop(&q2).(int)
225+
}
226+
suf[i] = s
227+
}
228+
ans := int64(1e18)
229+
for i := n; i <= n*2; i++ {
230+
ans = min(ans, int64(pre[i]-suf[i+1]))
231+
}
232+
return ans
233+
}
234+
235+
func min(a, b int64) int64 {
236+
if a < b {
237+
return a
238+
}
239+
return b
240+
}
241+
242+
type hp struct{ sort.IntSlice }
243+
244+
func (h hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
245+
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
246+
func (h *hp) Pop() interface{} {
247+
a := h.IntSlice
248+
v := a[len(a)-1]
249+
h.IntSlice = a[:len(a)-1]
250+
return v
251+
}
81252
```
82253

83254
### **TypeScript**
84255

85256
```ts
86-
257+
function minimumDifference(nums: number[]): number {
258+
const m = nums.length;
259+
const n = Math.floor(m / 3);
260+
let s = 0;
261+
const pre: number[] = Array(m + 1);
262+
const q1 = new MaxPriorityQueue();
263+
for (let i = 1; i <= n * 2; ++i) {
264+
const x = nums[i - 1];
265+
s += x;
266+
q1.enqueue(x, x);
267+
if (q1.size() > n) {
268+
s -= q1.dequeue().element;
269+
}
270+
pre[i] = s;
271+
}
272+
s = 0;
273+
const suf: number[] = Array(m + 1);
274+
const q2 = new MinPriorityQueue();
275+
for (let i = m; i > n; --i) {
276+
const x = nums[i - 1];
277+
s += x;
278+
q2.enqueue(x, x);
279+
if (q2.size() > n) {
280+
s -= q2.dequeue().element;
281+
}
282+
suf[i] = s;
283+
}
284+
let ans = Number.MAX_SAFE_INTEGER;
285+
for (let i = n; i <= n * 2; ++i) {
286+
ans = Math.min(ans, pre[i] - suf[i + 1]);
287+
}
288+
return ans;
289+
}
87290
```
88291

89292
### **...**

0 commit comments

Comments
 (0)