Skip to content

Commit

Permalink
feat: add solutions to lc problem: No.0016
Browse files Browse the repository at this point in the history
No.0016.3Sum Closest
  • Loading branch information
yanglbme committed Nov 24, 2022
1 parent 69434b0 commit d6d52d8
Show file tree
Hide file tree
Showing 12 changed files with 334 additions and 324 deletions.
26 changes: 13 additions & 13 deletions solution/0000-0099/0013.Roman to Integer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@ class Solution:
romans = {'I': 1, 'V': 5, 'X': 10,
'L': 50, 'C': 100, 'D': 500, 'M': 1000}
ans = 0
for i in range(len(s)-1):
if romans[s[i]] < romans[s[i+1]]:
for i in range(len(s) - 1):
if romans[s[i]] < romans[s[i + 1]]:
ans -= romans[s[i]]
else:
ans += romans[s[i]]
return ans+romans[s[-1]]
return ans + romans[s[-1]]
```

### **Java**
Expand Down Expand Up @@ -173,16 +173,16 @@ public:
```go
func romanToInt(s string) int {
romans := map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
ans := 0
for i := 0; i < len(s)-1; i++ {
if romans[s[i]] < romans[s[i+1]] {
ans -= romans[s[i]]
} else {
ans += romans[s[i]]
}
}
return ans + romans[s[len(s)-1]]
romans := map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
ans := 0
for i := 0; i < len(s)-1; i++ {
if romans[s[i]] < romans[s[i+1]] {
ans -= romans[s[i]]
} else {
ans += romans[s[i]]
}
}
return ans + romans[s[len(s)-1]]
}
```

Expand Down
26 changes: 13 additions & 13 deletions solution/0000-0099/0013.Roman to Integer/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ class Solution:
romans = {'I': 1, 'V': 5, 'X': 10,
'L': 50, 'C': 100, 'D': 500, 'M': 1000}
ans = 0
for i in range(len(s)-1):
if romans[s[i]] < romans[s[i+1]]:
for i in range(len(s) - 1):
if romans[s[i]] < romans[s[i + 1]]:
ans -= romans[s[i]]
else:
ans += romans[s[i]]
return ans+romans[s[-1]]
return ans + romans[s[-1]]
```

### **Java**
Expand Down Expand Up @@ -151,16 +151,16 @@ public:
```go
func romanToInt(s string) int {
romans := map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
ans := 0
for i := 0; i < len(s)-1; i++ {
if romans[s[i]] < romans[s[i+1]] {
ans -= romans[s[i]]
} else {
ans += romans[s[i]]
}
}
return ans + romans[s[len(s)-1]]
romans := map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
ans := 0
for i := 0; i < len(s)-1; i++ {
if romans[s[i]] < romans[s[i+1]] {
ans -= romans[s[i]]
} else {
ans += romans[s[i]]
}
}
return ans + romans[s[len(s)-1]]
}
```

Expand Down
20 changes: 10 additions & 10 deletions solution/0000-0099/0013.Roman to Integer/Solution.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
func romanToInt(s string) int {
romans := map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
ans := 0
for i := 0; i < len(s)-1; i++ {
if romans[s[i]] < romans[s[i+1]] {
ans -= romans[s[i]]
} else {
ans += romans[s[i]]
}
}
return ans + romans[s[len(s)-1]]
romans := map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
ans := 0
for i := 0; i < len(s)-1; i++ {
if romans[s[i]] < romans[s[i+1]] {
ans -= romans[s[i]]
} else {
ans += romans[s[i]]
}
}
return ans + romans[s[len(s)-1]]
}
3 changes: 2 additions & 1 deletion solution/0000-0099/0013.Roman to Integer/Solution.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class Solution:
def romanToInt(self, s: str) -> int:
romans = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
romans = {'I': 1, 'V': 5, 'X': 10,
'L': 50, 'C': 100, 'D': 500, 'M': 1000}
ans = 0
for i in range(len(s) - 1):
if romans[s[i]] < romans[s[i + 1]]:
Expand Down
187 changes: 107 additions & 80 deletions solution/0000-0099/0016.3Sum Closest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@

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

双指针解决。
**方法一:排序 + 双指针**

将数组排序,然后遍历数组,对于每个元素 $nums[i]$,我们使用指针 $j$ 和 $k$ 分别指向 $i+1$ 和 $n-1$,计算三数之和,如果三数之和等于 $target$,则直接返回 $target$,否则根据与 $target$ 的差值更新答案。如果三数之和大于 $target$,则将 $k$ 向左移动一位,否则将 $j$ 向右移动一位。

时间复杂度 $O(n^2)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组长度。

<!-- tabs:start -->

Expand All @@ -54,31 +58,22 @@
```python
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
def twoSumClosest(nums, start, end, target):
res = 0
diff = 10000
while start < end:
val = nums[start] + nums[end]
if val == target:
return val
if abs(val - target) < diff:
res = val
diff = abs(val - target)
if val < target:
start += 1
else:
end -= 1
return res

nums.sort()
res, n = 0, len(nums)
diff = 10000
for i in range(n - 2):
t = twoSumClosest(nums, i + 1, n - 1, target - nums[i])
if abs(nums[i] + t - target) < diff:
res = nums[i] + t
diff = abs(nums[i] + t - target)
return res
n = len(nums)
ans = inf
for i, v in enumerate(nums):
j, k = i + 1, n - 1
while j < k:
t = v + nums[j] + nums[k]
if t == target:
return t
if abs(t - target) < abs(ans - target):
ans = t
if t > target:
k -= 1
else:
j += 1
return ans
```

### **Java**
Expand All @@ -89,39 +84,86 @@ class Solution:
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int res = 0;
int ans = 1 << 30;
int n = nums.length;
int diff = Integer.MAX_VALUE;
for (int i = 0; i < n - 2; ++i) {
int t = twoSumClosest(nums, i + 1, n - 1, target - nums[i]);
if (Math.abs(nums[i] + t - target) < diff) {
res = nums[i] + t;
diff = Math.abs(nums[i] + t - target);
for (int i = 0; i < n; ++i) {
int j = i + 1, k = n - 1;
while (j < k) {
int t = nums[i] + nums[j] + nums[k];
if (t == target) {
return t;
}
if (Math.abs(t - target) < Math.abs(ans - target)) {
ans = t;
}
if (t > target) {
--k;
} else {
++j;
}
}
}
return res;
return ans;
}
}
```

private int twoSumClosest(int[] nums, int start, int end, int target) {
int res = 0;
int diff = Integer.MAX_VALUE;
while (start < end) {
int val = nums[start] + nums[end];
if (val == target) {
return val;
}
if (Math.abs(val - target) < diff) {
res = val;
diff = Math.abs(val - target);
}
if (val < target) {
++start;
} else {
--end;
### **C++**

```cpp
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int ans = 1 << 30;
int n = nums.size();
for (int i = 0; i < n; ++i) {
int j = i + 1, k = n - 1;
while (j < k) {
int t = nums[i] + nums[j] + nums[k];
if (t == target) return t;
if (abs(t - target) < abs(ans - target)) ans = t;
if (t > target) -- k;
else ++j;
}
}
return res;
return ans;
}
};
```
### **Go**
```go
func threeSumClosest(nums []int, target int) int {
sort.Ints(nums)
ans := 1 << 30
n := len(nums)
for i, v := range nums {
j, k := i+1, n-1
for j < k {
t := v + nums[j] + nums[k]
if t == target {
return t
}
if abs(t-target) < abs(ans-target) {
ans = t
}
if t > target {
k--
} else {
j++
}
}
}
return ans
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
```

Expand All @@ -134,43 +176,28 @@ class Solution {
* @return {number}
*/
var threeSumClosest = function (nums, target) {
let len = nums.length;
nums.sort((a, b) => a - b);
let diff = Infinity;
let res;
for (let i = 0; i < len - 2; i++) {
if (i > 0 && nums[i] === nums[i - 1]) continue;
let left = i + 1,
right = len - 1;
let cur = nums[i] + nums[i + 1] + nums[i + 2];
if (cur > target) {
let newDiff = Math.abs(cur - target);
if (newDiff < diff) {
diff = newDiff;
res = cur;
let ans = 1 << 30;
const n = nums.length;
for (let i = 0; i < n; ++i) {
let j = i + 1;
let k = n - 1;
while (j < k) {
const t = nums[i] + nums[j] + nums[k];
if (t == target) {
return t;
}
break;
}
while (left < right) {
cur = nums[i] + nums[left] + nums[right];
if (cur === target) return target;
let newDiff = Math.abs(cur - target);
if (newDiff < diff) {
diff = newDiff;
res = cur;
if (Math.abs(t - target) < Math.abs(ans - target)) {
ans = t;
}
if (cur < target) {
while (nums[left] === nums[left + 1]) left++;
left++;
continue;
if (t > target) {
--k;
} else {
while (nums[right] === nums[right - 1]) right--;
right--;
continue;
++j;
}
}
}
return res;
return ans;
};
```

Expand Down
Loading

0 comments on commit d6d52d8

Please sign in to comment.