恩,先夸一下leetcode,真的比lintcode强不少,无论是题的质量还是代码judging的速度来说。
来,切入正题。
16 .
3Sum Closest
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
这道题出的还是蛮有意思的,不跟以前的题一样一看就有思路。
首先看到题的第一反应就是遍历,但是想想3个数字遍历起来估计复杂度o(n^3),数组一大直接爆炸,不可以用这个方法。
搞定,附上代码,回头写思路。(赶着出去吃宵夜)
吃饱回来惹,这边的烧烤真心比深圳的好吃多了…还便宜。
好了废话不多说,继续上面的。
然后决定,先排序。(嗯没错,幸亏我之前机智的把排序复习了一波,现在直接ctrl+c,ctrl+v)
排序完了之后,每次固定一个数字i,然后另外两个数字,一个为前面固定的值的位置+1,为left;另外一个数字为数组最后一个值,为right。
然后计算i+left+right,如果大于target,那么就right–,小于target就left++;如果等于的话直接两次return出去return target;
i这么遍历完以后,再i+1继续…直到结束。
按这个方法遍历,然后每次计算D值(与target的差),都记着最小的D值的sum。最后返回sum即可。
嗨呀语言真的特别难描述算法这种东西,直接看代码吧。
public class Solution {
public static void main(String[] args) {
int [] nums={0,0,0};
int target=1;
Solution s=new Solution();
System.out.println(s.threeSumClosest(nums, target));
}
public int threeSumClosest(int[] nums, int target) {
quickSort(nums);
int nowSum=0;
int D=Integer.MAX_VALUE;
int minDSum=Integer.MIN_VALUE;
for(int i=0,l=nums.length;i<l;i++){
if(-2147483648==getMinDSum(i,nums,target)){
continue;
}
nowSum=getMinDSum(i,nums,target);
if(nowSum==target){
return nowSum;
}
if(getD(nowSum,target)<D){
minDSum=nowSum;
D=getD(nowSum,target);
}
}
return minDSum;
}
private static int getMinDSum(int i,int[] nums,int target){
//return : sum of three nums such that closest to target
int left=i+1;
int right=nums.length-1;
int nowSum=0;
int D=Integer.MAX_VALUE;
int minDSum=Integer.MIN_VALUE;
while(right>left){
nowSum=nums[i]+nums[left]+nums[right];
if(nowSum==target){
return nowSum;
}
if(getD(nowSum,target)<D){
D=getD(nowSum,target);
minDSum=nowSum;
}
if(nowSum>target){
right--;
}else if(nowSum<target){
left++;
}
}
return minDSum;
}
private static int getD(int a,int b){
return (a>b?a:b)-(a>b?b:a);
}
private static void quickSort(int[] arr) {
qs(arr, 0, arr.length - 1);
}
private static void qs(int[] arr, int start, int end) {
if (start == end) {
return;
}
int base = start;
int left = start + 1;
int right = end;
while (true) {
while ((arr[right] >= arr[base]) && (right > left)) {
right--;
}
while ((arr[left] <= arr[base]) && (left < right)) {
left++;
}
if (right == left) {
if (arr[left] < arr[base]) {
int tmp = arr[base];
arr[base] = arr[left];
arr[left] = tmp;
}
break;
} else {
int tmp = arr[right];
arr[right] = arr[left];
arr[left] = tmp;
}
}
qs(arr, start, right - 1);
if (right > end) {
qs(arr, end, end);
} else {
qs(arr, right , end);
}
}
}