3Sum Closest & 3Sum Smaller

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.

 Notice

You may assume that each input would have exactly one solution.

Example

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

 1 public class Solution {
 2     /**
 3      * @param numbers: Give an array numbers of n integer
 4      * @param target : An integer
 5      * @return : return the sum of the three integers, the sum closest target.
 6      */
 7     public int threeSumClosest(int[] num ,int target) {
 8         int tempClosestSum = Integer.MAX_VALUE;
 9         int diff = Integer.MAX_VALUE;
10         if(num == null || num.length < 3) {
11             return tempClosestSum;
12         }
13         Arrays.sort(num);
14         for (int i = 0; i < num.length - 2; i++) {
15             if (i != 0 && num[i] == num[i - 1]) {
16                 continue; // to skip duplicate numbers; e.g [0,0,0,0]
17             }
18 
19             int left = i + 1;
20             int right = num.length - 1;
21             while (left < right) {
22                 int sum = num[left] + num[right] + num[i];
23                 if (sum - target == 0) {
24                     return target;
25                 } else if (sum - target < 0) {
26                     if (Math.abs(sum - target) < Math.abs(tempClosestSum - target)) {
27                         tempClosestSum = sum;
28                     }
29                     left++;
30                 } else {
31                     if (Math.abs(sum - target) < Math.abs(tempClosestSum - target)) {
32                         tempClosestSum = sum;
33                     } 
34                     right--;
35                 }
36             }
37         }
38         return tempClosestSum;
39     }
40 }

3Sum Smaller

Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 <= i < j < k < n that satisfy the condition nums[i] + nums[j] + nums[k] < target.

For example, given nums = [-2, 0, 1, 3], and target = 2.

Return 2. Because there are two triplets which sums are less than 2:

[-2, 0, 1]
[-2, 0, 3]

分析:https://segmentfault.com/a/1190000003794736
解题思路和3SUM一样,也是先对整个数组排序,然后一个外层循环确定第一个数,然后里面使用头尾指针left和right进行夹逼,得到三个数的和。如果这个和大于或者等于目标数,说明我们选的三个数有点大了,就把尾指针right向前一位(因为是排序的数组,所以向前肯定会变小)。
如果这个和小于目标数,那就有right - left个有效的结果。为什么呢?因为假设我们此时固定好外层的那个数,还有头指针left指向的数不变,那把尾指针向左移0位一直到左移到left之前一位,这些组合都是小于目标数的。
 1     public int threeSumSmaller(int[] nums, int target) {
 2         // 先将数组排序
 3         Arrays.sort(nums);
 4         int cnt = 0;
 5         for (int i = 0; i < nums.length - 2; i++) {
 6             int left = i + 1, right = nums.length - 1;
 7             while (left < right) {
 8                 int sum = nums[i] + nums[left] + nums[right];
 9                 // 如果三个数的和大于等于目标数,那将尾指针向左移
10                 if (sum >= target) {
11                     right--;
12                     // 如果三个数的和小于目标数,那将头指针向右移
13                 } else {
14                     // right - left个组合都是小于目标数的
15                     cnt += right - left;
16                     left++;
17                 }
18             }
19         }
20         return cnt;
21     }

 

posted @ 2016-07-04 10:30  北叶青藤  阅读(207)  评论(0编辑  收藏  举报