43
43
44
44
<!-- 这里可写通用的实现逻辑 -->
45
45
46
- 双指针解决。
46
+ ** 方法一:排序 + 双指针**
47
+
48
+ 将数组排序,然后遍历数组,对于每个元素 $nums[ i] $,我们使用指针 $j$ 和 $k$ 分别指向 $i+1$ 和 $n-1$,计算三数之和,如果三数之和等于 $target$,则直接返回 $target$,否则根据与 $target$ 的差值更新答案。如果三数之和大于 $target$,则将 $k$ 向左移动一位,否则将 $j$ 向右移动一位。
49
+
50
+ 时间复杂度 $O(n^2)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组长度。
47
51
48
52
<!-- tabs:start -->
49
53
54
58
``` python
55
59
class Solution :
56
60
def threeSumClosest (self , nums : List[int ], target : int ) -> int :
57
- def twoSumClosest (nums , start , end , target ):
58
- res = 0
59
- diff = 10000
60
- while start < end:
61
- val = nums[start] + nums[end]
62
- if val == target:
63
- return val
64
- if abs (val - target) < diff:
65
- res = val
66
- diff = abs (val - target)
67
- if val < target:
68
- start += 1
69
- else :
70
- end -= 1
71
- return res
72
-
73
61
nums.sort()
74
- res, n = 0 , len (nums)
75
- diff = 10000
76
- for i in range (n - 2 ):
77
- t = twoSumClosest(nums, i + 1 , n - 1 , target - nums[i])
78
- if abs (nums[i] + t - target) < diff:
79
- res = nums[i] + t
80
- diff = abs (nums[i] + t - target)
81
- return res
62
+ n = len (nums)
63
+ ans = inf
64
+ for i, v in enumerate (nums):
65
+ j, k = i + 1 , n - 1
66
+ while j < k:
67
+ t = v + nums[j] + nums[k]
68
+ if t == target:
69
+ return t
70
+ if abs (t - target) < abs (ans - target):
71
+ ans = t
72
+ if t > target:
73
+ k -= 1
74
+ else :
75
+ j += 1
76
+ return ans
82
77
```
83
78
84
79
### ** Java**
@@ -89,39 +84,86 @@ class Solution:
89
84
class Solution {
90
85
public int threeSumClosest (int [] nums , int target ) {
91
86
Arrays . sort(nums);
92
- int res = 0 ;
87
+ int ans = 1 << 30 ;
93
88
int n = nums. length;
94
- int diff = Integer . MAX_VALUE ;
95
- for (int i = 0 ; i < n - 2 ; ++ i) {
96
- int t = twoSumClosest(nums, i + 1 , n - 1 , target - nums[i]);
97
- if (Math . abs(nums[i] + t - target) < diff) {
98
- res = nums[i] + t;
99
- diff = Math . abs(nums[i] + t - target);
89
+ for (int i = 0 ; i < n; ++ i) {
90
+ int j = i + 1 , k = n - 1 ;
91
+ while (j < k) {
92
+ int t = nums[i] + nums[j] + nums[k];
93
+ if (t == target) {
94
+ return t;
95
+ }
96
+ if (Math . abs(t - target) < Math . abs(ans - target)) {
97
+ ans = t;
98
+ }
99
+ if (t > target) {
100
+ -- k;
101
+ } else {
102
+ ++ j;
103
+ }
100
104
}
101
105
}
102
- return res ;
106
+ return ans ;
103
107
}
108
+ }
109
+ ```
104
110
105
- private int twoSumClosest (int [] nums , int start , int end , int target ) {
106
- int res = 0 ;
107
- int diff = Integer . MAX_VALUE ;
108
- while (start < end) {
109
- int val = nums[start] + nums[end];
110
- if (val == target) {
111
- return val;
112
- }
113
- if (Math . abs(val - target) < diff) {
114
- res = val;
115
- diff = Math . abs(val - target);
116
- }
117
- if (val < target) {
118
- ++ start;
119
- } else {
120
- -- end;
111
+ ### ** C++**
112
+
113
+ ``` cpp
114
+ class Solution {
115
+ public:
116
+ int threeSumClosest(vector<int >& nums, int target) {
117
+ sort(nums.begin(), nums.end());
118
+ int ans = 1 << 30;
119
+ int n = nums.size();
120
+ for (int i = 0; i < n; ++i) {
121
+ int j = i + 1, k = n - 1;
122
+ while (j < k) {
123
+ int t = nums[ i] + nums[ j] + nums[ k] ;
124
+ if (t == target) return t;
125
+ if (abs(t - target) < abs(ans - target)) ans = t;
126
+ if (t > target) -- k;
127
+ else ++j;
121
128
}
122
129
}
123
- return res ;
130
+ return ans ;
124
131
}
132
+ };
133
+ ```
134
+
135
+ ### **Go**
136
+
137
+ ```go
138
+ func threeSumClosest(nums []int, target int) int {
139
+ sort.Ints(nums)
140
+ ans := 1 << 30
141
+ n := len(nums)
142
+ for i, v := range nums {
143
+ j, k := i+1, n-1
144
+ for j < k {
145
+ t := v + nums[j] + nums[k]
146
+ if t == target {
147
+ return t
148
+ }
149
+ if abs(t-target) < abs(ans-target) {
150
+ ans = t
151
+ }
152
+ if t > target {
153
+ k--
154
+ } else {
155
+ j++
156
+ }
157
+ }
158
+ }
159
+ return ans
160
+ }
161
+
162
+ func abs(x int) int {
163
+ if x < 0 {
164
+ return -x
165
+ }
166
+ return x
125
167
}
126
168
```
127
169
@@ -134,43 +176,28 @@ class Solution {
134
176
* @return {number}
135
177
*/
136
178
var threeSumClosest = function (nums , target ) {
137
- let len = nums .length ;
138
179
nums .sort ((a , b ) => a - b);
139
- let diff = Infinity ;
140
- let res;
141
- for (let i = 0 ; i < len - 2 ; i++ ) {
142
- if (i > 0 && nums[i] === nums[i - 1 ]) continue ;
143
- let left = i + 1 ,
144
- right = len - 1 ;
145
- let cur = nums[i] + nums[i + 1 ] + nums[i + 2 ];
146
- if (cur > target) {
147
- let newDiff = Math .abs (cur - target);
148
- if (newDiff < diff) {
149
- diff = newDiff;
150
- res = cur;
180
+ let ans = 1 << 30 ;
181
+ const n = nums .length ;
182
+ for (let i = 0 ; i < n; ++ i) {
183
+ let j = i + 1 ;
184
+ let k = n - 1 ;
185
+ while (j < k) {
186
+ const t = nums[i] + nums[j] + nums[k];
187
+ if (t == target) {
188
+ return t;
151
189
}
152
- break ;
153
- }
154
- while (left < right) {
155
- cur = nums[i] + nums[left] + nums[right];
156
- if (cur === target) return target;
157
- let newDiff = Math .abs (cur - target);
158
- if (newDiff < diff) {
159
- diff = newDiff;
160
- res = cur;
190
+ if (Math .abs (t - target) < Math .abs (ans - target)) {
191
+ ans = t;
161
192
}
162
- if (cur < target) {
163
- while (nums[left] === nums[left + 1 ]) left++ ;
164
- left++ ;
165
- continue ;
193
+ if (t > target) {
194
+ -- k;
166
195
} else {
167
- while (nums[right] === nums[right - 1 ]) right-- ;
168
- right-- ;
169
- continue ;
196
+ ++ j;
170
197
}
171
198
}
172
199
}
173
- return res ;
200
+ return ans ;
174
201
};
175
202
```
176
203
0 commit comments