16. 3Sum Closest

题意:给定n个整数的数组S,找出S中最接近目标的3个数的和,返回和。

思路:由于题意只需要求和,不需要返回的元素的位置,那么可以先对数组排序,再求和

            优化: 1、已经找到3个元素的和为target,停止程序;

                         2、i : 0->length-3, j: 0->length-2, index = binarySearch(j+1, length,target – array[i] – array[j]),避免元素被重复计算多次,如数组【1,3,4,6】,目标为9,如果4被计算多次会得到9实际值为8,向后搜索,认为小于j的搜索域已取得最优值,只需向后搜索得到更优值。如果第三个值的下标为j+1说明j的循环需要结束。

	public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int twoSum, delta = Integer.MAX_VALUE;//minus and plus
        for(int i = 0; i < nums.length - 2; i++){
        	for(int j = i + 1; j < nums.length - 1; j++){//the last but one:gurantee j > i
        		twoSum = nums[i] + nums[j];
        		int last = target - twoSum;
        		int index = Arrays.binarySearch(nums, j+1, nums.length, last);
        		
        		if(index >= 0){ //avoid repetitivly add a num
        			return target;
        		}
        		
        		int insertionPoint = -(index + 1);
        		/*if(insertionPoint < i){
        			if(insertionPoint == 0){
        				
        			}
        			break; //already searched
        		}*/
        		
        		int temp;
        	/*	if(insertionPoint <= j || (insertionPoint - j == 1 && insertionPoint != nums.length)){ //search forward never push back
        			temp = twoSum + nums[j+1] - target; //plus
    				if(temp < ((delta > 0) ? delta : -delta)){
    					delta = temp;
    				}
    				break;
        		}*/
        		
        		if(insertionPoint == j+1){ //insertionPoint >= j+1
        			temp = twoSum + nums[j+1] - target; //plus
    				if(temp < ((delta > 0) ? delta : -delta)){
    					delta = temp;
    				}
    				break;

        		}
        /*		if(insertionPoint - j >= 2){//minus
        			temp = target - twoSum - nums[insertionPoint-1];
        			if(temp < ((delta > 0) ? delta : -delta)){
    					delta = -temp;
    				}
        		}*/
        		temp = target - twoSum - nums[insertionPoint-1];
    			if(temp < ((delta > 0) ? delta : -delta)){
					delta = -temp;
				}
        		if(insertionPoint  == nums.length){
        			continue;
        		}
        		temp = twoSum + nums[insertionPoint] - target;//the larger
        		if(temp < ((delta > 0) ? delta : -delta)){
					delta = temp; //plus
				}
        	}
        }
        return target + delta;
    }

         

点赞