15. 三数之和

leetcode15:15. 三数之和

题目描述

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

Example

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

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

solution idea

双指针法

三数之和可以解构成在二数之和问题的基础上,将target值变成变化的值。对数组进行遍历,每一个元素的值就是target的取值。

  • 为保证不重复,首先对数组进行排序,但不可去重。当target取值相同时,直接跳过即可,这是保证不重复需要注意的其中一点。另一点是在寻找两数之和满足target值时,若遇到相同元素(相同元素一定相邻),可直接跳过。
  • 用双指针是相对合适的解法,原因是双指针遍历时,可以结合先剪枝策略,从而降低平均耗时。
  • 先剪枝策略:前面的指针所访问的元素大于target时,可提前结束。
class Solution {
public:
/*
**  双指针法
*/
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> results;
        int length=nums.size();
        if (length<3) return results;
        //排序(降序)
        sort(nums.begin(),nums.end());
        for (vector<int>::iterator it=nums.begin(); it<nums.end()-2; )
        {
            int tmp=*it;
            if (tmp>0) break;
            vector<int>::iterator left=it+1;
            vector<int>::iterator right=nums.end()-1; //类似于下标索引从0开始,最后一个元素是 *(nums.end()-1)
            while(left<right)
            {
                if(*right<0) break;

                if((*left + *right +tmp)>0)
                {
                    int v_temp=*right;
                    while(left<right && *right==v_temp ) right--;//跳过相等的元素
                }
                else if((*left + *right +tmp)<0)
                {
                    int v_temp=*left;
                    while(left<right && *left==v_temp) left++;
                }
                else
                {
                    vector<int> result={tmp,*left,*right};//保存结果
                    results.push_back(result);

                    int v_temp=*right;
                    while(left<right && *right==v_temp ) right--;//跳过相等的元素

                    v_temp=*left;
                    while(left<right && *left==v_temp) left++;
                }
            }
            while(it != nums.end()-2 && *it == tmp) it++;//跳过相等的元素
        }
        return results;

    }
};
Tricks
std::sort
default (1)	
template <class RandomAccessIterator>
  void sort (RandomAccessIterator first, RandomAccessIterator last);
custom (2)	
template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);


Sorts the elements in the range [first,last) into ascending order.
The elements are compared using operator< for the first version, and comp for the second.
Equivalent elements are not guaranteed to keep their original relative order (see stable_sort).
iterator 迭代器

An iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range using a set of operators (with at least the increment (++) and dereference (*) operators).

迭代起的运算

在这里插入图片描述

迭代器支持的运算

在这里插入图片描述

begin 和end 运算符

an iterator pointing to the first/past-the-end element in the sequence

begin和end返回的具体类型由对象是否是常量决定
vector<int> v;
const vector<int> cv;
auto it1=v.begin(); // it1的类型是 vector<int>::iterator
auto it2=cv.begin(); // it2的类型是 vector<int>::const_iterator

参考文献

  1. c++ prime 第5版
  2. std::sort
  3. iterator
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值