leetcode 16. 最接近的三數之和(Java版)

題目描述(題目難度,中等)

給定一個包括 n 個整數的數組 nums 和 一個目標值 target。找出 nums 中的三個整數,使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。

例如,給定數組 nums = [-1,2,1,-4] 和 target = 1.
與 target 最接近的三個數的和爲 2 (-1 + 2 + 1 = 2)。

示例代碼

時間複雜度爲 O(n2)O(n^2)

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        // 排序
    	// 遍歷
    	// 尋找當前元素後面的最接近的兩數之和
    	// 		雙指針算法,等於就輸出,否則就向中間移動直至相遇
    	Arrays.sort(nums);
    	int closest = Integer.MAX_VALUE;
    	int direction = -1;
    	for(int i = 0; i < nums.length; ++i){
    		for(int j = i+1, k = nums.length-1; j < k;){
    			int sum = nums[i] + nums[j] + nums[k];
    			if(target == sum) return sum;
    			else if(target > sum){
    				if(target-sum < closest){
    					closest = target-sum;
    					direction = -1;
    				}
    				++j;
    			}else {
    				if(sum-target < closest){
    					closest = sum-target;
    					direction = 1;
    				}
					--k;
				}
    		}
    	}
    	return target + direction*closest;
    }
}

思路解析

本題的解法和leetcode 15. 三數之和(Java版的三種解法)中的解法二總體來說是一模一樣的。
我們需要理解的就是,有序數組的雙指針算法,不僅能找到和等於給定值的兩個數(如果存在的話),而且也能找到和最接近給定值的兩個數。
有序數組的雙指針算法只涉及前指針後移和後指針前移,直至兩指針相遇,時間複雜度爲 O(n)O(n),並沒有窮舉所有的兩數和情況,那麼會不會有漏掉的情況,即爲什麼可以前指針僅後移後指針僅前移呢?
下面給一個具體的實例,好理解一點:
例子
此時將 i 指針左移的話肯定不合理,因爲指向 1 和 8 的情況已經比較過了。
例子
此時如果將 i 指針左移,通過比較的傳遞性可以發現這種情況其實也已經比較過了,因爲當 i 指向 1,j 指向 8 時,已經小於 target 了(否則 i 不會後移),如果此時再指向 1 和 6,那就比之前指向 1 和 8 時更小於 target 了,肯定不會是最接近 target 的情況,可以排除掉。所以 i 指針一直後移即可,同理 j 指針一直前移即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章