写点什么

[算法练习]3 三数之和

作者:暖蓝笔记
  • 2022 年 3 月 13 日
  • 本文字数:1363 字

    阅读完需:约 4 分钟

一、题目:


三数之和


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


示例 1:


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


二、题解:


1.解读


已知目标值,遍历数据找出两个数,且和为目标值。首先想到的就是暴力求解,也可以排序后二分,更好的方法也可以用 Hash 求解。


2.思路 1


在思考两数之和解决方法的时候,我们使用了两层循环把所有的结果给求出来,相信大家很快就想到三数之和我就用三个循环,很棒,思路是一样,只是之前的 a+b=0,现在的 b=c+d 了。好了代码呈上。


3.思路 2


  • 第一步将整个数组排序

  • 从左侧开始,选定第一个数为定值比如下面的-4,然后左右指针分别指向对应位置如下图,是不是很像快排。

  • 定义的左右和定值相加

  • 如果等于 0,记录下三个值

  • 如果小于 0,左指针右移动

  • 如果大于 0,右指针左移

  • 然后定值右移,重复这个步骤


4.实现


在前面的两数之和的基础上,将目标值移动到左边等于 0 就转换为了上一次的练习题。二第二种方式采用先排队,然后两边夹击的方式求解。


三、代码:


class Solution {public:    vector<int> twoSum(vector<int>& nums, int target) {        //int result[]={0.1};        int i=  0;        int j=0;        for(i;i<nums.size()-1;i++)        {            for(j=i+1;j<nums.size();j++)            {                if(nums[i]+nums[j]==target)//numb i + numbs[j] - target = 0                {                    return {i,j};                }            }        }        return {i,j};    }};
复制代码


class Solution {public:    vector<vector<int>> threeSum(vector<int>& nums) {         int target;        vector<vector<int>> ans;        sort(nums.begin(), nums.end());        for (int i = 0; i < nums.size(); i++) {            if (i > 0 && nums[i] == nums[i - 1]) continue;            if ((target = nums[i]) > 0) break;            int left = i + 1, right = nums.size() - 1;            //取出三个数 所以不用left=right            while (left < right) {                if (nums[left] + nums[right] + target < 0) ++left;                else if (nums[left] + nums[right] + target > 0) --right;                else {                    ans.push_back({target, nums[left], nums[right]});                    ++left, --right;                    //去重                     //测试数据[-2,0,0,2,2]                    while (left < right && nums[left] == nums[left - 1]) ++left;                    while (left < right && nums[right] == nums[right + 1]) --right;                }            }        }        return ans;     }};
复制代码


时间复杂度:O(n ^ 2)


空间复杂度:O(n)


四、总结


文中使用了两种方式来解决这个问题,第一种为复杂度较高的暴力解答,第二种使用了类似快排思想的双指针法,后面还会有更多关于双指针的用法,敬请期待。至此,想想有学会点什么了?

用户头像

暖蓝笔记

关注

还未添加个人签名 2019.10.15 加入

银行国企上岸

评论

发布
暂无评论
[算法练习]3 三数之和_3 月月更_暖蓝笔记_InfoQ写作平台