LeetCode 15 3Sum

来源:互联网 发布:js 数组对象合并 编辑:程序博客网 时间:2024/06/08 11:26

本题出处 来自LeetCode Algorithms中的一道Medium的题
原题目:

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.

For example, given array S = [-1, 0, 1, 2, -1, -4],

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

题目大意:从给定的数组中找出一组数a, b, c。满足a+b+c=0的条件,要求最终的结果不能重复出现。

题目分析:通过样例输出可以,最终输出结果需要按照升序的结果输出。所以,在实现时,需要进行排序。下面说说解题的两种思路。

  • 第一种:三层循环,使用三层变量i∈[0, size-2), j∈[i+1, size-1), z∈[j+1, size)]从左往右列举所有可能的组合加以判。
    在此类方法中,首先对数组进行排序,得到升序的数组[-4, -1, -1, 0, 1, 2],并且在每一层变量查重(通过判断变量后一位是否越界,并且是否与本位相同即可)。简单易实现。但时间复杂度为O(n^3),显然算法是不够好的。

  • 第二种:使用两个指示指针,从两个方向(从左往右,从右往左)同时移动来列举所有可能的组合。使用一层循环变量i∈[0, size-2),并设置两个指示指针front∈[i+1, back), back∈(front, size)。使用此方法,减少了循环嵌套的深度,时间复杂度缩减至O(n^2)

此处附上方法2的代码

vector<vector<int> >threeSum(vector<int> nums) {    vector<vector<int> > ret;    vector<int> temp;    for (int i = 0; i < nums.size(); ++i) {        sort(nums.begin(), nums.end())        int target = -nums[i];        int front = i + 1;        int back = nums.size()-1;        if (target < 0) break;        while (front < back) {            int sum = nums[front] + nums[back];            if (sum > target) back--;            else if (sum < target) front++;            else {                temp.push_back(nums[i]);                temp.push_back(nums[front]);                temp.push_back(nums[back]);                ret.push_back(temp);                while (front < back && nums[front] == temp[1]) front++;                while (front < back && nums[back] == temp[2]) back--;            }        }        while (i < nums.size() && nums[i] == tmep[0]) i++;    }    return ret;}

时间复杂度为O(n^2)
具体的解释留个坑,尽快补上。

原创粉丝点击