LeetCode面试必备100题:3Sum 数组中查找三个和为零的数

作者:Linux猿

简介:CSDN博客专家,C/C++、面试、刷题、算法尽管咨询我,关注我,有问题私聊!

关注专栏:LeetCode面试常考100题 (优质好文持续更新中……)

一、题意

给定一个整数数组 nums,返回所有的三元组 [nums[i], nums[j], nums[k]] 使得 i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0。

注意:解决方案集中不能包含重复的三元组。

二、测试样例

输入:nums = [-1,0,1,2,-1,-4]

输出:[[-1,-1,2],[-1,0,1]]

三、解题思路

一句话来说就是:先确定第一个数,然后查找另外两个数的和等于第一个数的相反数,这样三个数的和即为 0。

详细分析:先将数组从小到大排序(用于查找另外两个数),然后依次遍历数组,先确定第一个数 nums[k],然后在这个数后面查找两个数的和是第一个数的相反数(这样三个数相加和为 0)。那么,接下来就是查找另外两个数啦!只需要对排序后的数组,使用两个指针从数组两头(这里指 k+1 ~ n-1)向中间遍历即可。

剪枝操作:

(1)nums[k] > 0 ,遍历数组结束,因为后面所有的数都为正数,没有符合三个数相加等于0的组合;

(2)k > 0 时,nums[k] == nums[k-1],nums[k] 不处理,因为当前数 nums[k] 和前一个数相同,会找到重复的; 

时间复杂度:遍历数组的时间复杂度为 O(n),每次查找另外两个数的时间复杂度是O(n),因为两个是嵌套的,时间复杂度要相乘,所以总的时间复杂度为O(n^2)。

四、代码实现

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ret; // 存储返回值 
        sort(nums.begin(), nums.end());   //数组排序
        for (int k = 0; k < nums.size(); ++k) {   //依次遍历
            if (nums[k] > 0) break;                 //后面都是正数就不考虑了
            if (k > 0 && nums[k] == nums[k - 1]) continue;     //相等于会重复也不考虑
            int target = -nums[k];   //查找 k + 1 ~ nums.size() - 1 中两个数的和等于 -nums[k]
            int i = k + 1, j = nums.size() - 1;
            while (i < j) {
                if (nums[i] + nums[j] == target) {
                    ret.push_back({nums[k], nums[i], nums[j]});
                    while (i < j && nums[i] == nums[i + 1]) ++i;
                    while (i < j && nums[j] == nums[j - 1]) --j;
                    ++i; --j;
                } else if (nums[i] + nums[j] < target) ++i;
                else --j;
            }
        }
        return ret;
    }
};

五、题目链接

3Sum

 关注专栏:LeetCode面试常考100题 (优质好文持续更新中……)

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 26
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值