Skip to content

Commit dd81c72

Browse files
committedOct 20, 2022
feat: add solutions to lc problem: No.1755
No.1755.Closest Subsequence Sum
1 parent bf3429d commit dd81c72

File tree

2 files changed

+314
-2
lines changed

2 files changed

+314
-2
lines changed
 

‎solution/1700-1799/1755.Closest Subsequence Sum/README.md

+159-2
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@
5454

5555
**方法一:DFS + 二分查找**
5656

57-
每个数选或不选两种可能,所以 `n` 个数就有 `2^n` 种组合,由于 `n` 最大为 40,枚举 `2^40` 种组合显然会超时。
57+
每个数选或不选两种可能,所以 $n$ 个数就有 $2^n$ 种组合,由于 $n$ 最大为 $40$,枚举 $2^{40}$ 种组合显然会超时。
5858

59-
可以把数组分成左右两部分,分别求出两部分所有子序列和(`2 * 2^(n/2)` 种组合)记为 `lsum``rsum`。最后,只需找到最接近 `goal``lsum[i] + rsum[j]`
59+
我们可以把数组分成左右两部分,分别求出两部分所有子序列和,记为 $left$ 和 $right$。最后,只需找到最接近 $goal$ 的 $left[i] + right[j]$。
60+
61+
时间复杂度 $O(n\times 2^{n/2})$。
6062

6163
<!-- tabs:start -->
6264

@@ -99,6 +101,32 @@ class Solution:
99101
self.getSubSeqSum(i + 1, curr + arr[i], arr, result)
100102
```
101103

104+
```python
105+
class Solution:
106+
def minAbsDifference(self, nums: List[int], goal: int) -> int:
107+
def dfs(arr, res, i, s):
108+
if i == len(arr):
109+
res.add(s)
110+
return
111+
dfs(arr, res, i + 1, s)
112+
dfs(arr, res, i + 1, s + arr[i])
113+
114+
n = len(nums)
115+
left, right = set(), set()
116+
dfs(nums[: n >> 1], left, 0, 0)
117+
dfs(nums[n >> 1:], right, 0, 0)
118+
right = sorted(right)
119+
ans = inf
120+
for l in left:
121+
x = goal - l
122+
i = bisect_left(right, x)
123+
if i < len(right):
124+
ans = min(ans, abs(x - right[i]))
125+
if i:
126+
ans = min(ans, abs(x - right[i - 1]))
127+
return ans
128+
```
129+
102130
### **Java**
103131

104132
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -149,6 +177,49 @@ class Solution {
149177
}
150178
```
151179

180+
```java
181+
class Solution {
182+
public int minAbsDifference(int[] nums, int goal) {
183+
int n = nums.length;
184+
Set<Integer> left = new HashSet<>();
185+
Set<Integer> right = new HashSet<>();
186+
dfs(nums, 0, n >> 1, 0, left);
187+
dfs(nums, n >> 1, n, 0, right);
188+
List<Integer> rs = new ArrayList<>(right);
189+
Collections.sort(rs);
190+
int ans = Integer.MAX_VALUE;
191+
for (int x : left) {
192+
int y = goal - x;
193+
int l = 0, r = rs.size();
194+
while (l < r) {
195+
int mid = (l + r) >> 1;
196+
if (rs.get(mid) >= y) {
197+
r = mid;
198+
} else {
199+
l = mid + 1;
200+
}
201+
}
202+
if (l < rs.size()) {
203+
ans = Math.min(ans, Math.abs(y - rs.get(l)));
204+
}
205+
if (l > 0) {
206+
ans = Math.min(ans, Math.abs(y - rs.get(l - 1)));
207+
}
208+
}
209+
return ans;
210+
}
211+
212+
private void dfs(int[] arr, int i, int n, int s, Set<Integer> res) {
213+
if (i == n) {
214+
res.add(s);
215+
return;
216+
}
217+
dfs(arr, i + 1, n, s, res);
218+
dfs(arr, i + 1, n, s + arr[i], res);
219+
}
220+
}
221+
```
222+
152223
### **Go**
153224

154225
```go
@@ -210,6 +281,60 @@ func abs(x int) int {
210281
}
211282
```
212283

284+
```go
285+
func minAbsDifference(nums []int, goal int) int {
286+
n := len(nums)
287+
left := []int{}
288+
right := []int{}
289+
dfs(nums[:n>>1], &left, 0, 0)
290+
dfs(nums[n>>1:], &right, 0, 0)
291+
sort.Ints(right)
292+
ans := math.MaxInt32
293+
for _, x := range left {
294+
y := goal - x
295+
l, r := 0, len(right)
296+
for l < r {
297+
mid := (l + r) >> 1
298+
if right[mid] >= y {
299+
r = mid
300+
} else {
301+
l = mid + 1
302+
}
303+
}
304+
if l < len(right) {
305+
ans = min(ans, abs(y-right[l]))
306+
}
307+
if l > 0 {
308+
ans = min(ans, abs(y-right[l-1]))
309+
}
310+
}
311+
return ans
312+
}
313+
314+
func dfs(arr []int, res *[]int, i, s int) {
315+
if i == len(arr) {
316+
*res = append(*res, s)
317+
return
318+
}
319+
dfs(arr, res, i+1, s)
320+
dfs(arr, res, i+1, s+arr[i])
321+
}
322+
323+
func abs(x int) int {
324+
if x < 0 {
325+
return -x
326+
}
327+
return x
328+
}
329+
330+
func min(a, b int) int {
331+
if a < b {
332+
return a
333+
}
334+
return b
335+
}
336+
```
337+
213338
### **C++**
214339

215340
```cpp
@@ -260,6 +385,38 @@ private:
260385
};
261386
```
262387

388+
```cpp
389+
class Solution {
390+
public:
391+
int minAbsDifference(vector<int>& nums, int goal) {
392+
int n = nums.size();
393+
vector<int> left;
394+
vector<int> right;
395+
dfs(nums, left, 0, n >> 1, 0);
396+
dfs(nums, right, n >> 1, n, 0);
397+
sort(right.begin(), right.end());
398+
int ans = INT_MAX;
399+
for (int x : left) {
400+
int y = goal - x;
401+
int idx = lower_bound(right.begin(), right.end(), y) - right.begin();
402+
if (idx < right.size()) ans = min(ans, abs(y - right[idx]));
403+
if (idx) ans = min(ans, abs(y - right[idx - 1]));
404+
}
405+
return ans;
406+
}
407+
408+
private:
409+
void dfs(vector<int>& arr, vector<int>& res, int i, int n, int s) {
410+
if (i == n) {
411+
res.emplace_back(s);
412+
return;
413+
}
414+
dfs(arr, res, i + 1, n, s);
415+
dfs(arr, res, i + 1, n, s + arr[i]);
416+
}
417+
};
418+
```
419+
263420
### **...**
264421
265422
```

‎solution/1700-1799/1755.Closest Subsequence Sum/README_EN.md

+155
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,32 @@ class Solution:
8888
self.getSubSeqSum(i + 1, curr + arr[i], arr, result)
8989
```
9090

91+
```python
92+
class Solution:
93+
def minAbsDifference(self, nums: List[int], goal: int) -> int:
94+
def dfs(arr, res, i, s):
95+
if i == len(arr):
96+
res.add(s)
97+
return
98+
dfs(arr, res, i + 1, s)
99+
dfs(arr, res, i + 1, s + arr[i])
100+
101+
n = len(nums)
102+
left, right = set(), set()
103+
dfs(nums[: n >> 1], left, 0, 0)
104+
dfs(nums[n >> 1:], right, 0, 0)
105+
right = sorted(right)
106+
ans = inf
107+
for l in left:
108+
x = goal - l
109+
i = bisect_left(right, x)
110+
if i < len(right):
111+
ans = min(ans, abs(x - right[i]))
112+
if i:
113+
ans = min(ans, abs(x - right[i - 1]))
114+
return ans
115+
```
116+
91117
### **Java**
92118

93119
```java
@@ -136,6 +162,49 @@ class Solution {
136162
}
137163
```
138164

165+
```java
166+
class Solution {
167+
public int minAbsDifference(int[] nums, int goal) {
168+
int n = nums.length;
169+
Set<Integer> left = new HashSet<>();
170+
Set<Integer> right = new HashSet<>();
171+
dfs(nums, 0, n >> 1, 0, left);
172+
dfs(nums, n >> 1, n, 0, right);
173+
List<Integer> rs = new ArrayList<>(right);
174+
Collections.sort(rs);
175+
int ans = Integer.MAX_VALUE;
176+
for (int x : left) {
177+
int y = goal - x;
178+
int l = 0, r = rs.size();
179+
while (l < r) {
180+
int mid = (l + r) >> 1;
181+
if (rs.get(mid) >= y) {
182+
r = mid;
183+
} else {
184+
l = mid + 1;
185+
}
186+
}
187+
if (l < rs.size()) {
188+
ans = Math.min(ans, Math.abs(y - rs.get(l)));
189+
}
190+
if (l > 0) {
191+
ans = Math.min(ans, Math.abs(y - rs.get(l - 1)));
192+
}
193+
}
194+
return ans;
195+
}
196+
197+
private void dfs(int[] arr, int i, int n, int s, Set<Integer> res) {
198+
if (i == n) {
199+
res.add(s);
200+
return;
201+
}
202+
dfs(arr, i + 1, n, s, res);
203+
dfs(arr, i + 1, n, s + arr[i], res);
204+
}
205+
}
206+
```
207+
139208
### **Go**
140209

141210
```go
@@ -197,6 +266,60 @@ func abs(x int) int {
197266
}
198267
```
199268

269+
```go
270+
func minAbsDifference(nums []int, goal int) int {
271+
n := len(nums)
272+
left := []int{}
273+
right := []int{}
274+
dfs(nums[:n>>1], &left, 0, 0)
275+
dfs(nums[n>>1:], &right, 0, 0)
276+
sort.Ints(right)
277+
ans := math.MaxInt32
278+
for _, x := range left {
279+
y := goal - x
280+
l, r := 0, len(right)
281+
for l < r {
282+
mid := (l + r) >> 1
283+
if right[mid] >= y {
284+
r = mid
285+
} else {
286+
l = mid + 1
287+
}
288+
}
289+
if l < len(right) {
290+
ans = min(ans, abs(y-right[l]))
291+
}
292+
if l > 0 {
293+
ans = min(ans, abs(y-right[l-1]))
294+
}
295+
}
296+
return ans
297+
}
298+
299+
func dfs(arr []int, res *[]int, i, s int) {
300+
if i == len(arr) {
301+
*res = append(*res, s)
302+
return
303+
}
304+
dfs(arr, res, i+1, s)
305+
dfs(arr, res, i+1, s+arr[i])
306+
}
307+
308+
func abs(x int) int {
309+
if x < 0 {
310+
return -x
311+
}
312+
return x
313+
}
314+
315+
func min(a, b int) int {
316+
if a < b {
317+
return a
318+
}
319+
return b
320+
}
321+
```
322+
200323
### **C++**
201324

202325
```cpp
@@ -247,6 +370,38 @@ private:
247370
};
248371
```
249372

373+
```cpp
374+
class Solution {
375+
public:
376+
int minAbsDifference(vector<int>& nums, int goal) {
377+
int n = nums.size();
378+
vector<int> left;
379+
vector<int> right;
380+
dfs(nums, left, 0, n >> 1, 0);
381+
dfs(nums, right, n >> 1, n, 0);
382+
sort(right.begin(), right.end());
383+
int ans = INT_MAX;
384+
for (int x : left) {
385+
int y = goal - x;
386+
int idx = lower_bound(right.begin(), right.end(), y) - right.begin();
387+
if (idx < right.size()) ans = min(ans, abs(y - right[idx]));
388+
if (idx) ans = min(ans, abs(y - right[idx - 1]));
389+
}
390+
return ans;
391+
}
392+
393+
private:
394+
void dfs(vector<int>& arr, vector<int>& res, int i, int n, int s) {
395+
if (i == n) {
396+
res.emplace_back(s);
397+
return;
398+
}
399+
dfs(arr, res, i + 1, n, s);
400+
dfs(arr, res, i + 1, n, s + arr[i]);
401+
}
402+
};
403+
```
404+
250405
### **...**
251406
252407
```

0 commit comments

Comments
 (0)