LeetCode – 3Sum Closest (Java)

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).

Analysis

This problem is similar to 2 Sum. This kind of problem can be solved by using a similar approach, i.e., two pointers from both left and right.

Java Solution

public int threeSumClosest(int[] nums, int target) {
    int min = Integer.MAX_VALUE;
	int result = 0;
 
	Arrays.sort(nums);
 
	for (int i = 0; i < nums.length; i++) {
		int j = i + 1;
		int k = nums.length - 1;
		while (j < k) {
			int sum = nums[i] + nums[j] + nums[k];
			int diff = Math.abs(sum - target);
 
			if(diff == 0) return sum;
 
			if (diff < min) {
				min = diff;
				result = sum;
			}
			if (sum <= target) {
				j++;
			} else {
				k--;
			}
		}
	}
 
	return result;
}

Time Complexity is O(n^2).

Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • Piotr Aleksander

    Looks so. Can You proof that? Thanks.

  • Udaydeep Thota

    Wouldn’t it be sufficient if the main loop is iterated only till nums.length-2. Thanks.

  • Matias SM

    Your solution assumes the 3 values must be next to each other, which is not true. E.g. {1,3,5,7} tgt = 13

  • Brenda

    This doesn’t work for

    Input:[1,1,1,0]
    Target:100

    Output:
    2

    Expected:3

  • ryanlr

    fixed.

  • jason zhang

    Can be converted to a binary search problem after sorting.

    The runtime is NlogN(sorting)+logN(binary search)=NlogN

    The code is here: https://github.com/jasonzhang2022/algorithm/blob/master/src/main/java/jason/algorithm/practice/ThreeSumClosest.java

  • Happyman

    public int threeSumCloset(int[]numbers, int target){
    if (numbers == null || numbers.length < 3){
    return Integer.MAX_VALUE;
    }
    int min = Integer.MAX_VALUE / 2;
    int result = Integer.MAX_VALUE / 2;
    Arrays.sort(numbers);
    int length = numbers.length;
    for (int i = 0; i numbers[i – 1]){
    int start = i + 1;
    int end = length – 1;
    while (start Math.abs(sum – target)){
    min = Math.abs(sum – target);
    result = sum;
    }

    start++;
    end–;

    while (start < end && numbers[start] == numbers[start – 1]){
    start++;
    }
    while (start < end && numbers[end] == numbers[end + 1]){
    end–;
    }
    }
    }
    }

    return result;
    }
    }

  • Chris

    if(diff == 0) return 0; is wrong, you should return sum instead.

  • theLastUnicorn

    Shouldn’t it be
    if(diff == 0) return target;

    instead of 0?

  • King Fdk

    Can this be done using c++ implementation, I’m not able to do it …

  • jason

    you should return target if diff equals 0

  • ryanlr

    Not necessarily. Because different combinations can still have the same sum value. An extreme case: given array {1, 1, 1, 1, 1} and target value 1.

  • ryanlr

    Absolutely helpful. Added!

  • Arendale

    “You may assume that each input would have exactly one solution” Does this mean no duplicates in array?

  • Hi, good code!

    But I think add this line of code:

    if (diff == 0) return sum;

    behind the code:

    int diff = Math.abs(sum – target);

    maybe makes the run time shorter?

  • Yuqing Chen

    Like your code. Always short and clean, plus easy to understand following a logic. Thumbs up!