1. 程式人生 > >Leetcode演算法Java全解答--16. 最接近的三數之和

Leetcode演算法Java全解答--16. 最接近的三數之和

Leetcode演算法Java全解答–16. 最接近的三數之和

題目

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

示例:

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

想法

  1. 暴力破解法:
    迴圈三輪
  2. 使用前面三數之和的邏輯
    1. 排序陣列
    2. 以第一個數為起點,後面2數進行滑動列表操作

結果

超過99%的測試案

時間複雜度:n2

空間複雜度:1

總結

程式碼

我的答案

暴力破解

   /**
     * 暴力破解
     * 超過5%的測試案例
     * 時間複雜度:n3
     * 空間複雜度:1
     *
     * @param nums   陣列
     * @param target 目標值
     * @return 結果
     */
    public int threeSumClosestByBrute(int[] nums, int target) {
        if (nums == null || nums.length < 3) {
            return 0;
        }

        int comp = Integer.MAX_VALUE;
        int result = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                for (int k = j + 1; k < nums.length; k++) {
                    int tmp = nums[i] + nums[j] + nums[k];
                    if (comp > Math.abs(tmp - target)) {
                        comp = Math.abs(tmp - target);
                        result = tmp;
                    }
                }
            }
        }

        return result;
    }

滑動列表

/**
     *      時間複雜度:n2
     *      空間複雜度:1
     * 程式碼執行過程:
     *
     * 總結:
     *
     * ***********************************/
    public int threeSumClosest(int[] nums, int target) {

        if (nums == null || nums.length < 3) {
            return 0;
        }
        Arrays.sort(nums);

        int comp = Integer.MAX_VALUE;
        int result = Integer.MAX_VALUE;

        for (int i = 0; i < nums.length; i++) {
            // 如果和之前那個資料相同,則會是重複事件
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }

            int leftIndex = i + 1;
            int rightIndex = nums.length - 1;

            // 滑動列表
            while (leftIndex < rightIndex) {
                int tmp = nums[leftIndex] + nums[rightIndex] + nums[i];
                if (comp > Math.abs(tmp - target)) {
                    comp = Math.abs(tmp - target);
                    result = tmp;
                }

                if (tmp > target) {
                    rightIndex--;
                } else if (tmp < target) {
                    leftIndex++;
                } else {
                    // 差值為0,最爽了,直接返回
                    return tmp;
                }
            }
        }
        return result;
    }

大佬們的答案

    /**************************************
     * 比我好的答案 better
     * ***********************************/
    public int better(int[] nums, int target) {

        int result = nums[0] + nums[1] + nums[2];
        Arrays.sort(nums);
        for (int i = 0; i < nums.length - 2; i++) {
            int start = i + 1, end = nums.length - 1;

            while (start < end) {
                int tmpSum = nums[i] + nums[start] + nums[end];
                if (Math.abs(tmpSum - target) < Math.abs(result - target)) {
                    result = tmpSum;
                }
                if (tmpSum < target) {
                    start++;
                } else if (tmpSum > target) {
                    end--;
                } else {
                    return result;
                }

            }
        }
        return result;
    }

測試用例

    @Test
    public void test016() {
        // 建立測試案例
        int[] arr1 = new int[] { -1, 2, 1, -4 };
        int target1 = 1;

        // 測試案例期望值
        int expResult1 = 2;

        // 執行方法
        Solution016 solution016 = new Solution016();
        int result1 = solution016.threeSumClosest(arr1,target1);

        // 判斷期望值與實際值
        Assert.assertEquals(expResult1, result1);

    }

其他

程式碼託管碼雲地址:https://gitee.com/lizhaoandroid/LeetCodeAll.git

檢視其他內容可以點選專欄或者我的部落格哈:https://blog.csdn.net/cmqwan

“大佬們的答案” 標籤來自leetcode,侵權請聯絡我進行刪改

如有疑問請聯絡,聯絡方式:QQ3060507060