leetcode【数组】-----15.3Sum

版权声明: https://blog.csdn.net/zl6481033/article/details/88193321

1、题目描述

2、分析

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

        首先,分析这道题,要找到三个数和为0,那么除了三个数全为0的情况,肯定会有正数和负数。那么就可以先确定一个数,然后找到另外两个数的和是它的相反数就好。我们排除掉暴力遍历的做法,如果数组有序,那么就可以使用双指针以线性的时间复杂度来遍历满足要求的两个数。

        对原数组的排序使用C++自带排序函数,时间复杂度是nlogn。在开始之前我们可以做一些边界处理和剪枝优化。比如如果第一个数是正数,那么就可以直接跳出,因为后面的数都是正数,相加不可能等于0。同理,最后一个数不能是负数。在找的过程中,还要跳过重复的数字,如果我们确定的数字和前面的数字相同那么就会产生和前面定位的数字一样的结果。对定位的数字,用0减去,得到一个目标值target。然后只要在数组中剩下的数字中找到两个和为target的数字就好。如果相等那么就存入结果中。另外,两个指针都要检查重复数字。如果两数之和小于target,那么左指针向后移动,如果大于,那么右指针向前移动。

3、代码

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        if (nums.empty() || nums.back() < 0 || nums.front() > 0) return {};
        for (int k = 0; k < nums.size(); ++k) {
            //if (nums[k] > 0) break;
            if (k > 0 && nums[k] == nums[k - 1]) continue;
            int target = 0 - nums[k];
            int left = k + 1, right = nums.size() - 1;
            while (left < right) {
                if (nums[left] + nums[right] == target) {
                    res.push_back({nums[k], nums[left],nums[right]});
                    while (left < right && nums[left] == nums[left + 1]) ++left;
                    while (left < right && nums[left] == nums[right - 1]) --right;
                    ++left; --right;
                } else if (nums[left] + nums[right] < target) ++left;
                else --right;
            }
        }
        return res;
    }
};

4、涉及知识点

        双指针遍历数组是一个常用的方法,C++中二维数组的定义和具体用法,边界条件的处理和特殊情况的处理。

        

猜你喜欢

转载自blog.csdn.net/zl6481033/article/details/88193321