15. 三數之和

題目地址(3sum/">15. 三數之和)

https://leetcode.cn/problems/3sum/

題目描述

給你一個整數數組 nums ,判斷是否存在三元組 [nums[i], nums[j], nums[k]] 滿足 i != j、i != k 且 j != k ,同時還滿足 nums[i] + nums[j] + nums[k] == 0 。請

你返回所有和為 0 且不重復的三元組。

注意:答案中不可以包含重復的三元組。

前置知識

  • 雙指針法

公司

  • 暫無

思路

  • 雙指針法

關鍵點

  • 1)去重,需要排序然后才方便判斷,第一個數和第二個數都需要判斷重復,我這里兩個去重方法都放在最后
  • 2)最精妙之處,還是雙指針法,j = i + 1, k = n - 1(末尾)
    • 情況1.nums[j] + nums[k] < target,此時只需要j++即可
    • 情況2.nums[j] + nums[k] > target,此時k--即可
    • 關鍵問題,k--后,要不要還原k到n-1,答案是不用,因為數組已經排過序了,j++后,想要j,k位置兩數之和為target,k必然是一直--

代碼

  • 語言支持:Java

Java Code:


class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        int n = nums.length;
        if (null == nums || n < 3) {
            return null;
        }
        // 依次將數組的第一個元素作為target,然后在剩下的數組尋找兩個之和為target的數
        List<List<Integer>> result = new ArrayList<>();
        // 排序是為了去重方便
        Arrays.sort(nums);
        for (int i = 0; i < n - 2;)  {
            // 雙指針法
            int j = i + 1;
            int k = n - 1;
            int target = - nums[i];
            while (j < k) {
                while (j < k && nums[j] + nums[k] > target) {
                    k--;
                }
                // 這里不能少了j < k,否則當j == k時,會一個位置取兩次
                if (j < k && nums[j] + nums[k] == target) {
                    result.add(new ArrayList<>(Arrays.asList(nums[i], nums[j], nums[k])));  
                }
                j++;
                // 跳過重復的j
                while (j < k && nums[j] == nums[j - 1]) {
                    j++;
                }    
            }
            i++;
            while (i < n - 2 && nums[i] == nums[i - 1]) {
                i++;
            }
        }
        return result;
    }
}

Go code:

func threeSum(nums []int) [][]int {
    if (nums == nil || len(nums) < 3) {
        return nil
    }
    n := len(nums)
    // sort標準庫
    sort.Ints(nums)
    // 使用make,才能append
    result := make([][]int, 0)
    for i := 0; i < n - 2; {
        j, k, target := i + 1, n - 1, - nums[i]
        for j < k {
            for j < k && nums[j] + nums[k] > target {
                k--
            }

            if j < k && nums[j] + nums[k] == target {
                // append是builtin標準庫
                result = append(result, []int{nums[i], nums[j], nums[k]})
            }

            j++
            for j < k && nums[j] == nums[j - 1] {
                j++
            } 
        }
        i++
        for i < n - 2 && nums[i] == nums[i - 1] {
            i++
        }
    }
    return result
}

復雜度分析

令 n 為數組長度。

  • 時間復雜度:O(n^2)
  • 空間復雜度:就是排序的空間復雜度,如果需要復制,則是O(n)
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容