Skip to content

Commit e34ee97

Browse files
committed
feat: add solutions to lc problem: No.1099
No.1099.Two Sum Less Than K
1 parent bf87d81 commit e34ee97

File tree

7 files changed

+316
-84
lines changed

7 files changed

+316
-84
lines changed

solution/1000-1099/1096.Brace Expansion II/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@
7575

7676
我们设计一个递归函数 $dfs(exp)$,用于处理表达式 $exp$,并将结果存入集合 $s$ 中。
7777

78-
对于表达式 $exp$,我们首先找到第一个右花括号的位置 $j$,如果 $j = -1$,说明 $exp$ 中没有右花括号,即 $exp$ 为单一元素,直接将 $exp$ 加入集合 $s$ 中即可。
78+
对于表达式 $exp$,我们首先找到第一个右花括号的位置 $j$,如果找不到,说明 $exp$ 中没有右花括号,即 $exp$ 为单一元素,直接将 $exp$ 加入集合 $s$ 中即可。
7979

8080
否则,我们从位置 $j$ 开始往左找到第一个左花括号的位置 $i$,此时 $exp[:i]$ 和 $exp[j + 1:]$ 分别为 $exp$ 的前缀和后缀,记为 $a$ 和 $c$。而 $exp[i + 1: j]$ 为 $exp$ 中花括号内的部分,即 $exp$ 中的子表达式,我们将其按照逗号分割成多个字符串 $b_1, b_2, \cdots, b_k$,然后对每个 $b_i$,我们将 $a + b_i + c$ 拼接成新的表达式,递归调用 $dfs$ 函数处理新的表达式,即 $dfs(a + b_i + c)$。
8181

8282
最后,我们将集合 $s$ 中的元素按照字典序排序,即可得到答案。
8383

84-
时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为表达式 $expression$ 的长度。
84+
时间复杂度约为 $O(n \times 2^{n / 4})$,其中 $n$ 为表达式 $expression$ 的长度。
8585

8686
<!-- tabs:start -->
8787

solution/1000-1099/1099.Two Sum Less Than K/README.md

Lines changed: 143 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,25 @@
4141

4242
<!-- 这里可写通用的实现逻辑 -->
4343

44-
先进行排序,再用双指针 `low``high` 分别指向排序数组的首尾,遍历获取满足条件的和 `nums[low] + nums[high]` 并求最大和。
44+
**方法一:排序 + 二分查找**
45+
46+
我们可以先对数组 `nums` 进行排序,初始化答案为 `-1`
47+
48+
接下来,我们枚举数组中的每个元素 `nums[i]`,并在数组中寻找满足 `nums[j] + nums[i] < k` 的最大的 `nums[j]`。这里我们可以使用二分查找来加速寻找过程。如果找到了这样的 `nums[j]`,那么我们就可以更新答案,即 `ans = max(ans, nums[i] + nums[j])`
49+
50+
枚举结束后,返回答案即可。
51+
52+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 是数组 `nums` 的长度。
53+
54+
**方法二:排序 + 双指针**
55+
56+
与方法一类似,我们可以先对数组 `nums` 进行排序,初始化答案为 `-1`
57+
58+
接下来,我们使用双指针 $i$ 和 $j$ 分别指向数组的左右两端,每次判断 `nums[i] + nums[j]` 是否小于 `k`,如果小于 `k`,那么我们就可以更新答案,即 `ans = max(ans, nums[i] + nums[j])`,并将 $i$ 右移一位,否则将 $j$ 左移一位。
59+
60+
枚举结束后,返回答案即可。
61+
62+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 是数组 `nums` 的长度。
4563

4664
<!-- tabs:start -->
4765

@@ -53,16 +71,27 @@
5371
class Solution:
5472
def twoSumLessThanK(self, nums: List[int], k: int) -> int:
5573
nums.sort()
56-
low, high = 0, len(nums) - 1
57-
res = -1
58-
while low < high:
59-
val = nums[low] + nums[high]
60-
if val < k:
61-
res = max(res, val)
62-
low += 1
74+
ans = -1
75+
for i, x in enumerate(nums):
76+
j = bisect_left(nums, k - x, lo=i + 1) - 1
77+
if i < j:
78+
ans = max(ans, x + nums[j])
79+
return ans
80+
```
81+
82+
```python
83+
class Solution:
84+
def twoSumLessThanK(self, nums: List[int], k: int) -> int:
85+
nums.sort()
86+
ans = -1
87+
i, j = 0, len(nums) - 1
88+
while i < j:
89+
if (t := nums[i] + nums[j]) < k:
90+
ans = max(ans, t)
91+
i += 1
6392
else:
64-
high -= 1
65-
return res
93+
j -= 1
94+
return ans
6695
```
6796

6897
### **Java**
@@ -73,18 +102,47 @@ class Solution:
73102
class Solution {
74103
public int twoSumLessThanK(int[] nums, int k) {
75104
Arrays.sort(nums);
76-
int low = 0, high = nums.length - 1;
77-
int res = -1;
78-
while (low < high) {
79-
int val = nums[low] + nums[high];
80-
if (val < k) {
81-
res = Math.max(res, val);
82-
++low;
105+
int ans = -1;
106+
int n = nums.length;
107+
for (int i = 0; i < n; ++i) {
108+
int j = search(nums, k - nums[i], i + 1, n) - 1;
109+
if (i < j) {
110+
ans = Math.max(ans, nums[i] + nums[j]);
111+
}
112+
}
113+
return ans;
114+
}
115+
116+
private int search(int[] nums, int x, int l, int r) {
117+
while (l < r) {
118+
int mid = (l + r) >> 1;
119+
if (nums[mid] >= x) {
120+
r = mid;
83121
} else {
84-
--high;
122+
l = mid + 1;
85123
}
86124
}
87-
return res;
125+
return l;
126+
}
127+
}
128+
```
129+
130+
```java
131+
class Solution {
132+
public int twoSumLessThanK(int[] nums, int k) {
133+
Arrays.sort(nums);
134+
int ans = -1;
135+
int i = 0, j = nums.length - 1;
136+
while (i < j) {
137+
int t = nums[i] + nums[j];
138+
if (t < k) {
139+
ans = Math.max(ans, t);
140+
++i;
141+
} else {
142+
--j;
143+
}
144+
}
145+
return ans;
88146
}
89147
}
90148
```
@@ -96,22 +154,79 @@ class Solution {
96154
public:
97155
int twoSumLessThanK(vector<int>& nums, int k) {
98156
sort(nums.begin(), nums.end());
99-
int low = 0, high = nums.size() - 1;
100-
int res = -1;
101-
while (low < high) {
102-
int val = nums[low] + nums[high];
103-
if (val < k) {
104-
res = max(res, val);
105-
++low;
157+
int ans = -1, n = nums.size();
158+
for (int i = 0; i < n; ++i) {
159+
int j = lower_bound(nums.begin() + i + 1, nums.end(), k - nums[i]) - nums.begin() - 1;
160+
if (i < j) {
161+
ans = max(ans, nums[i] + nums[j]);
162+
}
163+
}
164+
return ans;
165+
}
166+
};
167+
```
168+
169+
```cpp
170+
class Solution {
171+
public:
172+
int twoSumLessThanK(vector<int>& nums, int k) {
173+
sort(nums.begin(), nums.end());
174+
int ans = -1;
175+
int i = 0, j = nums.size() - 1;
176+
while (i < j) {
177+
int t = nums[i] + nums[j];
178+
if (t < k) {
179+
ans = max(ans, t);
180+
++i;
106181
} else {
107-
--high;
182+
--j;
108183
}
109184
}
110-
return res;
185+
return ans;
111186
}
112187
};
113188
```
114189

190+
### **Go**
191+
192+
```go
193+
func twoSumLessThanK(nums []int, k int) int {
194+
sort.Ints(nums)
195+
ans := -1
196+
for i, x := range nums {
197+
j := sort.SearchInts(nums[i+1:], k-x) + i
198+
if v := nums[i] + nums[j]; i < j && ans < v {
199+
ans = v
200+
}
201+
}
202+
return ans
203+
}
204+
```
205+
206+
```go
207+
func twoSumLessThanK(nums []int, k int) int {
208+
sort.Ints(nums)
209+
ans := -1
210+
i, j := 0, len(nums)-1
211+
for i < j {
212+
if t := nums[i] + nums[j]; t < k {
213+
ans = max(ans, t)
214+
i++
215+
} else {
216+
j--
217+
}
218+
}
219+
return ans
220+
}
221+
222+
func max(a, b int) int {
223+
if a > b {
224+
return a
225+
}
226+
return b
227+
}
228+
```
229+
115230
### **...**
116231

117232
```

0 commit comments

Comments
 (0)