• 15.3Sum


    Description

    Given an array nums of n integers, are there elements a, b, c in nums 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.

    Example:

    Given array nums = [-1, 0, 1, 2, -1, -4],
    
    A solution set is:
    [
      [-1, 0, 1],
      [-1, -1, 2]
    ]
    题目传送门

    一.题目理解

    这是LeetCode的第15题,主要方法是双指针和数组。

    题目要求给定含n个元素的数组,找出其中三个相加为0的元素,并把找到的所有情况返回。

    二.题目解答

    题目好理解,但是有一些细节值得注意。
    1. 找出所有的情况
    2. 返回的三元组不能重复

    因为,我们需要思考的是:

    1. 如何对数据去重,防止三元组重复
    2. 如何快速的搜索到符合条件的三元组

    1.set方法

    类比第1题,这道题可以认为是随机给定一个值(三元组中第一个数),我们把它当作target值,然后再剩余数组中搜索有没有两数之和等于这个数的相反数。可以看到,这很像第1到题,但与第1题不同的是,答案不是唯一解,而且元素有重复的,因而这里不再适合使用unordered_map。

    如何使考虑到的元素不重复,也就是在处理之前或处理之中把重复的数字筛选出去,我们立刻想到STL中set是不重复的,但是如果在搜索前过滤数据到set中,在搜索过程中还要进行某些重复的工作,效率并不高,那是不是能在筛选元素的过程中直接进行处理呢?答案是可以的。

    下面是代码:

    class Solution {
    public:
        vector<vector<int>> threeSum(vector<int>& nums) {
    
            vector<vector<int>> ans;
            unordered_set<int> s;
            sort(nums.begin(),nums.end());
    
            for(int i = 0; i < nums.size(); i++) {
               //去重1
                if(i != 0 && nums[i - 1] == nums[i])
                    continue;
    
                s.clear();
                for(int j = i + 1; j < nums.size(); j++) {
                    if(s.count(-nums[i] - nums[j])) {
                        ans.push_back({nums[i],nums[j],-nums[i] - nums[j]});
                      //去重2
                        while(nums[j + 1] == nums[j] && j + 1 < nums.size())
                            j++;
                    }
                    s.insert(nums[j]);
                }
    
            }
    
            return ans;
    
        }
    };

    可以看到,我们去重操作用了两步,第一步是为了防止处理相同的target值,这是因为每次处理不同的target值的时候,符合条件的已经全部找出,下一次如果target值相同,得到的解必然重复);第二步是为了防止出现相同的三元组解,这是因为前两个元素固定了,最后一个元素必然唯一。

    2.双指针方法

    首先这是个数组,其次要求解的问题与数组元素的值相关,而且对重复值有要求,因为我们可以对其进行预处理以减少操作,这里所做的预处理就是排序。

    经过预处理之后,数组变得”良好”,终止条件也比较明确,如果第一个元素就已经是正数,后面的数字一定全部是正数,这样它们的和肯定不是0;其次,再处理元素时,我们可以方便的把要处理的元素和已处理的元素作比较,如果相同,我们也可以跳过,这样对于冗余元素的数组,我们可以大大提高处理速度。

    class Solution {
    public:
        vector<vector<int>> threeSum(vector<int>& nums) {
    
            vector<vector<int>> ret;
            vector<int> vec;
            int target;
            int front,rear;
    
            sort(nums.begin(),nums.end());
    
            for(int i = 0; i < nums.size(); i++) {
    
                target = -nums[i];
    
                if(target < 0)
                    break;
                
                if(i != 0 && nums[i] == nums[i - 1])
                    continue;
                
                front = i + 1;
                rear = nums.size() - 1;
                while(front < rear) {
                    int sum = nums[front] + nums[rear];
                    if(sum < target)
                        front++;
                    else if(sum > target)
                        rear--;
                    else {
                        vector<int>().swap(vec);
                        vec.push_back(nums[i]);
                        vec.push_back(nums[front]);
                        vec.push_back(nums[rear]);
                        ret.push_back(vec);
    
                        //去重
                        while(front < rear && nums[front] == vec[1])
                            front++;
                        while(front < rear && nums[rear] == vec[2])
                            rear--;
                    }
                }       
            }
            return ret;
        }
    };

     

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
  • 相关阅读:
    【转】VB 技巧一
    VB中的trim()函数
    转:vb实现老板键功能
    VB为自己的程序设定消息(可接收处理)
    RegisterHotKey的具体使用方法
    GetPrivateProfileString
    在VB语言中,DOEVENTS的具体的用法和含义
    VB中的ADO数据对象编程
    jquery操作select下拉列表框
    jQuery对Select的操作集合
  • 原文地址:https://www.cnblogs.com/ovs98/p/9839571.html
Copyright © 2020-2023  润新知