栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

68 三数之和(3Sum)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

68 三数之和(3Sum)

文章目录
    • 1 题目
    • 2 解决方案
      • 2.1 思路
      • 2.2 时间复杂度
      • 2.3 空间复杂度
    • 3 源码

1 题目

题目:三数之和(3Sum)
描述:给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组。三元组(a, b, c)要求a≤b≤c。结果不能包含重复的三元组。

lintcode题号——57,难度——medium

样例1:

输入:numbers = [2,7,11,15]
输出:[]
解释:找不到三元组使得三个数和为0。

样例2:

输入:numbers = [-1,0,1,2,-1,-4]
输出:[[-1, 0, 1],[-1, -1, 2]]
解释:[-1, 0, 1]和[-1, -1, 2]是符合条件的2个三元组。
2 解决方案 2.1 思路

  考虑循环遍历数组,固定其中一个数,再在剩下的子数组中找到和为目标值的两数即可。

2.2 时间复杂度

  外层循环时间复杂度O(n),twoSum的时间复杂度O(n),总时间复杂度为O(n^2)。

2.3 空间复杂度

  使用了vector数据结构,空间复杂度为O(n)。

3 源码

细节:

  1. 先对数组进行排序。
  2. 使用循环固定其中一个数,再进行twoSum——在子数组中找到和为目标值的两数。
  3. 因为需要去重,所以先排序,跳过与前一个数相同的数,在第一个数的循环和twoSum循环中都需要做去重。

C++版本:

vector> threeSum(vector &numbers) {
    // write your code here
    vector> results;
    if (numbers.empty())
    {
        return results;
    }

    // 先对数组排序
    sort(numbers.begin(), numbers.end());

    // 固定其中一个数,再对后面的数组进行twoSum()
    for (int i = 0; i < numbers.size() - 2; i++)
    {
        //第一个数去重
        if (i != 0 && numbers.at(i) == numbers.at(i - 1))
        {
            continue;
        }

        int target = -numbers.at(i);
        vector> temp = twoSum(numbers, i + 1, numbers.size() - 1, target);
        for (auto it : temp)
        {
            it.insert(it.begin(), numbers.at(i));
            results.push_back(it);
        }
    }

    return results;
}

vector> twoSum(vector & numbers, int left, int right, int target)
{
    vector> results;

    while (left < right)
    {
        if (numbers.at(left) + numbers.at(right) < target)
        {
            left++;
        }
        else if (numbers.at(left) + numbers.at(right) > target)
        {
            right--;
        }
        else
        {
            vector temp;
            temp.push_back(numbers.at(left));
            temp.push_back(numbers.at(right));
            results.push_back(temp);
            left++;
            right--;

            // twoSum中也需要去重
            while (left < right && numbers.at(left) == numbers.at(left - 1))
            {
                left++;
            }
            while (left < right && numbers.at(right) == numbers.at(right + 1))
            {
                right--;
            }
        }
    }

    return results;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/864130.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号