15 三数之和

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

示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

主要思路:
(1)对于在一个数组中找到两个数之和为0的方法:可以先将数组进行排序nums,再使用双指针,分别指向第一个元素left和最后一个元素right,则比较nums[left]+nums[right]和0 的关系:
(a)若是等于零,则表示这两个元素满足要求;
(b)若是小于零,则说明这两个值之和需要增大,则++left;
(c)若是大于零,则说明这两个值之和需要减小,则–right;
(2)该问题描述中需要的是三个数之和为零,则可以增加一个新的指针now,指向第一个数,则left和right可以在此基础上,使用上述方法,处理now之后的所有的可能的组合,则当将now从头到尾遍历了,也就获得了所有的可能的组合;
(3)由于需要处理重复的组合的情形,故需要在获得满足要求的组合后,对后面的可能和left或right指向的值相等的元素,进行跳过;

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    	//处理特殊的情形
        if(nums.size()<3)
            return vector<vector<int>>();
        //排序
        sort(nums.begin(),nums.end());
        //处理特殊的情形
        if(nums[0]>0||nums[nums.size()-1]<0)
            return vector<vector<int>>();
        //声明三个指针,既索引
        int now=0;
        int left=now+1;
        int right=nums.size()-1;
        vector<vector<int>> result;
        //使用now遍历元素
        while(now<nums.size()-2){
        	//声明临时变量存储当前的以now为开头的三个元素的可能的组合
            vector<int>tmp(3);
            tmp[0]=nums[now];
            //left和right的初值,既遍历now之后的范围
            left=now+1;
            right=nums.size()-1;
            while(left<right){
                if(nums[now]+nums[left]+nums[right]==0){
                    tmp[1]=nums[left];
                    tmp[2]=nums[right];
                    result.emplace_back(tmp);
                   //去除重复的情形
                    while(left<right&&nums[left]==tmp[1])
                        ++left;
                    while(right>left&&nums[right]==tmp[2])
                        --right;
                }
                else if(nums[now]+nums[left]+nums[right]<0){          
                     ++left;
                }
                else{                
                     --right;      
                }
            }
            //去除重复的情形
            while(now<nums.size()-2&&nums[now]==tmp[0])
                ++now;
        }
        return result;
    }
};
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值