给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

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

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

自己的思路:如果追求思路简单,就是暴力的去求解每三个字符的和是否为0,但是有三层循环,时间复杂度太高,提交,超出时间限制。

(1)

  • 排序。排序可以让数据变得有序,在许多算法中都有使用。
  • 定义三个指针i,left,right.
  • i用来遍历数据,从下下标为0一直到len-3。
  • 对于每一个i,令left=i+1,right=len-1,然后检查三个指针所指数据的和,

    如果为0,说明找到一个符合条件的组合,把三个数放入vector中然后再放入map中,接着把left++,right--。

    如果>0,则说明当前的right偏大,则把right--,因为是排序的,所以整体和会变小。

    如果<0,说明当前的left偏小,则把left++,因为是排序的,所以整体的和会变大。(这里变大变小不是一定的,因为可能存在重复的数据,不影响)

    vector<vector<int>> threeSum(vector<int>& nums)
    { vector<vector<int>> result;
    int len = nums.size();
    map<vector<int>,int> m;
    if(nums.empty()||len<3) return result;
    sort(nums.begin(),nums.end());
    vector<int> res;
    int p1,p2,p3;
    int i=0;
    for(p1=0;p1<=len-3;p1++)
    {
    int left=p1+1;
    int right = len-1;
    while(left<right)
    {
    if(nums[p1]+nums[left]+nums[right]==0)
    {
    res.push_back(nums[p1]);
    res.push_back(nums[left]);
    res.push_back(nums[right]);
    if(!m.count(res))
    {
    m.insert(map<vector<int>,int>::value_type(res,i++));
    result.push_back(res);
    }
    res.clear();
    left++;
    right--;
    }
    else if(nums[p1]+nums[left]+nums[right]<0)
    left++;
    else
    right--;
    }
    }
    return result;
    }

    这里用map和map中的count函数是为了去除相同的组合,因为数组是排序好的,所以找到的组合也是排序好的,如果相同的话,是完全相同的,否则我们还得先排序才能比较。

  • (2)大神们还有比这个更加快速的解决方案,那就是

    vector<vector<int>> threeSum(vector<int>& nums)
    {
    vector<vector<int>> rs;
    vector<int> res;
    if(nums.size() == 0) return rs;
    sort(nums.begin(), nums.end());//先对目标数组进行从小到大的排序
    for (int i = 0; i < nums.size() - 2; i++)
    {
    if (nums[i] > 0) return rs;//如果最小值都大于0,那么就不用再找了
    if (i > 0 && nums[i] == nums[i-1]) //如果和前一个值相等,就跳过,去重
    continue;
    int tmpTarget = 0 - nums[i];//接下来就求nums[i]的相反数 int beg = i + 1, end = nums.size() - 1;//也是从两边开始往中间查找
    while (beg < end)
    {
    if (nums[beg] + nums[end] == tmpTarget)
    {
    res.push_back(nums[i]);
    res.push_back(nums[beg]);
    res.push_back(nums[end]);
    rs.push_back(res);
    while(beg < end - 1 && nums[end] == nums[end-1]) //同样是和前一个相同,去重
    end--;
    end--;
    res.clear();
    }
    else if (nums[beg] + nums[end] > tmpTarget)
    end--;
    else
    beg++;
    }
    }
    return rs;
    }

Leetcode(15)-三数之和的更多相关文章

  1. LeetCode 15. 三数之和(3Sum)

    15. 三数之和 15. 3Sum 题目描述 Given an array nums of n integers, are there elements a, b, c in nums such th ...

  2. Java实现 LeetCode 15 三数之和

    15. 三数之和 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以 ...

  3. LeetCode——15. 三数之和

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...

  4. LeetCode 15. 三数之和(3Sum)

    题目描述 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复 ...

  5. [Leetcode 15]三数之和 3 Sum

    [题目] Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? ...

  6. [LeetCode]15. 三数之和(数组)(双指针)

    题目 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三 ...

  7. [LeetCode] 15. 三数之和

    题目链接:https://leetcode-cn.com/problems/3sum/ 题目描述: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a ...

  8. LeetCode:三数之和【15】

    LeetCode:三数之和[15] 题目描述 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的 ...

  9. 代码随想录第七天| 454.四数相加II、383. 赎金信 、15. 三数之和 、18. 四数之和

    第一题454.四数相加II 给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <= i, ...

  10. leetcode题目15.三数之和(中等)

    题目描述: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重 ...

随机推荐

  1. Ubuntu20.04 安装火狐开发者版本(水狐)步骤

    1. 从Mozilla Firefox Developer Edition webpage下载. 2. 将下载的"tar.bz2"文件解压到指定目录, 例如/opt/firefox ...

  2. uni-app开发经验分享一: 多页面传值的三种解决方法

    开发了一年的uni-app,在这里总结一些uni-app开发中的问题,提供几个解决方法,分享给大家: 问题描述:一个主页面,需要联通一到两个子页面,子页面传值到主页面,主页面更新 问题难点: 首先我们 ...

  3. 网络流量预测入门(二)之LSTM介绍

    目录 网络流量预测入门(二)之LSTM介绍 LSTM简介 Simple RNN的弊端 LSTM的结构 细胞状态(Cell State) 门(Gate) 遗忘门(Forget Gate) 输入门(Inp ...

  4. 详解Mybatis拦截器(从使用到源码)

    详解Mybatis拦截器(从使用到源码) MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能. 本文从配置到源码进行分析. 一.拦截器介绍 MyBatis 允许你在 ...

  5. [从源码学设计] Flume 之 memory channel

    [从源码学设计] Flume 之 memory channel 目录 [从源码学设计] Flume 之 memory channel 0x00 摘要 0x01 业务范畴 1.1 用途和特点 1.2 C ...

  6. 最全面的图卷积网络GCN的理解和详细推导,都在这里了!

    目录 目录 1. 为什么会出现图卷积神经网络? 2. 图卷积网络的两种理解方式 2.1 vertex domain(spatial domain):顶点域(空间域) 2.2 spectral doma ...

  7. (十三)整合 SpringSecurity 框架,实现用户权限管理

    整合 SpringSecurity 框架,实现用户权限管理 1.Security简介 1.1 基础概念 1.2 核心API解读 2.SpringBoot整合SpringSecurity 2.1 流程描 ...

  8. 调试lcd时候给linux单板移植tslib

    作者:良知犹存 转载授权以及围观:欢迎添加微信公众号:Conscience_Remains 总述  tslib背景: 在采用触摸屏的移动终端中,触摸屏性能的调试是个重要问题之一,因为电磁噪声的缘故,触 ...

  9. HDU5213 Lucky【容斥+莫队】

    HDU5213 Lucky 题意: 给出\(N\)个数和\(k\),有\(m\)次询问,每次询问区间\([L1,R1]\)和区间\([L2,R2]\)中分别取一个数能相加得到\(k\)的方案数 题解: ...

  10. 【poj 1961】Period(字符串--KMP 模版题)

    题意:给你一个字符串,求这个字符串到第 i 个字符为止的重复子串的个数. 解法:判断重复子串的语句很重要!!if (p && i%(i-p)==0) printf("%d % ...