16. 3Sum Closest

最后更新

三刷。

还是双指针。

因为不用查重了,反而简单了。每次遇到更接近的值更新一下。

public class Solution {
    public int threeSumClosest(int[] nums, int target) {
        int res = 0;
        int diff = Integer.MAX_VALUE;
        
        Arrays.sort(nums);
        
        for (int i = 0; i < nums.length; i++) {
            if (i != 0 && nums[i] == nums[i-1]) continue;
            
            int l = i + 1;
            int r = nums.length - 1;
            while (l < r) {
                int total = nums[l] + nums[r] + nums[i];
                if (total == target) {
                    return total;
                } else if (total < target) {
                    l ++;
                } else {
                    r --;
                }
                
                if (Math.abs(total - target) < diff) {
                    diff = Math.abs(total - target);
                    res = total;
                }
            }
        }
        
        return res;
    }
}

一刷

和经典的3SUM一样。。只不过找最小的

几乎就是暴力搜索,只不过也减去一些
减去的时候是target - n- l - r == 0 那就是最小的了 不用找了 直接返还0

然后根据大了小了R--或者L++

一开始妄图在R--和L++的基础上进行BREAK 比如递增的时候增了那就不用了 其实不是 因为有正负。。

就不用那么贪了

另一个需要注意的是 定量SUM L+R+N 比较好 要不容易弄混了。。

public int threeSumClosest(int[] nums, int target) {
        if(nums.length == 3) return nums[0]+nums[1]+nums[2];

        boolean init = true;
        int res = 0;
        Arrays.sort(nums);
        int min = Integer.MAX_VALUE;
        for(int n = 0; n < nums.length;n++)
        {
        	int L = n + 1;
        	int R = nums.length-1;
        	
        	
        	while(L < R)
        	{
        	    if(init)
        	    {
        	        res = nums[L] + nums[R] + nums[n];
        	        init = false;
        	    }
        		int temp = target - nums[n] - nums[L] - nums[R];
        		if(Math.abs(temp) < min)
        		{
        		    min = Math.abs(temp);
        		    res = nums[L] + nums[R] + nums[n];
        		    
        		}

        		if(min == 0) return nums[L] + nums[R] + nums[n];
        		if(temp > 0 && L < R)
        		{
        			L++;
        		}

        		else if(temp < 0 && L < R)
        		{
        			R--;
        		}

        		
        	}
        }


        return res;
    }

有套路。。滑动窗口求段数

3SUM其实是固定一个 然后滑窗 这就是套路。
希望面试的时候能有思路




二刷。

SUM之类这种基本就是滑窗,二刷一眼就知道套路了。。

public class Solution 
{
    public int threeSumClosest(int[] nums, int target) 
    {
        if(nums.length == 3) return nums[0] + nums[1] + nums[2];
        
        Arrays.sort(nums);
        
        int res = 0;
        int min = Integer.MAX_VALUE;
        for(int i = 0; i < nums.length - 2;i++)
        {
            int L = i + 1;
            int R = nums.length -1;
            int left = target - nums[i];
            
            while(L < R)
            {
                
                if(nums[L]+nums[R] == left) return target;
            

                    
                if(Math.abs(nums[i]+nums[L]+nums[R]-target) < min)
                {
                    res = nums[i] + nums[L] + nums[R];
                    min = Math.abs(nums[i]+nums[L]+nums[R]-target);
                }
            
                if(nums[L]+nums[R] > left)
                {
                    R--;
                }
                else if (nums[L]+nums[R] < left)
                {
                    L++;
                }    
                
            }
            
            if(nums[i+1] == nums[i]) i++;
            
        }
        
        return res;
    }
}

感觉没啥可说的。