算法題丨3Sum

描述

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.git

示例

Given array S = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

算法分析

難度:中
分析:要求給定的數組,找出知足條件的3個元素組合,使得3個元素之和等於零。注意,元素不能重複(值能夠相同)。
思路:首先,咱們須要對數組進行排序,好比數組排序後變爲[-4, -1, -1, 0, 1, 2],咱們判斷第一個元素-4,判斷它以後是否有2個元素的和等於4,若是有的話知足條件。由於數組已經排序,只要向當前元素以後查找便可,不用往前查找;
接下來,咱們開始遍歷排序後的數組,假設當前元素是x,判斷本次遍歷有解的條件能夠轉化爲找到當前元素以後2個元素和,應該等於0-x,使用夾逼查找方法,檢查是否有解,若是有,增長到返回隊列,沒有的話,進入下一次的遍歷,直至找到全部知足條件組合。github

代碼示例(C#)

public IList<IList<int>> ThreeSum(int[] nums)
{
    //排序
    Array.Sort(nums);
    var res = new List<IList<int>>();

    //當前元素向後匹配2個元素,因此最後2個元素不用被遍歷
    for (int i = 0; i < nums.Length - 2; i++)
    {
        if (i == 0 || (i > 0 && nums[i] != nums[i - 1]))
        {
            int lo = i + 1, hi = nums.Length - 1, sum = 0 - nums[i];
            while (lo < hi)
            {
                //找到知足條件元素,添加到返回結果隊列
                if (nums[lo] + nums[hi] == sum)
                {
                    res.Add(new List<int> { nums[i], nums[lo], nums[hi] });
                    //防止重複元素
                    while (lo < hi && nums[lo] == nums[lo + 1]) lo++;
                    while (lo < hi && nums[hi] == nums[hi - 1]) hi--;
                    //夾逼查找
                    lo++; hi--;
                }
                else if (nums[lo] + nums[hi] < sum) lo++;
                else hi--;
            }
        }
    }
    return res;
}

複雜度

  • 時間複雜度O (n²).
  • 空間複雜度O (1).

附錄

相關文章
相關標籤/搜索