[leetcode数组系列]2三数之和

前言

秋招的结束,面试了大大小小的公司,最大的问题在于算法上。所以打算坚持在leetcode打卡,看看到底能不能行,如果你想见证,那我来开车,你坐稳,一起走向更好的远方。

在学习今天内容之前,先学习上一篇的两数之和会更好哟
leetcode两数之和求解

一 题目

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

1 leetcode链接

https://leetcode-cn.com/problems/3sum/

示例

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

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

2 思路1---暴力解法

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

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        if(nums.size()<3) return{};
        vector<vector<int>> res;//结果
        set<vector<int>> ret;//用来去重
        for(int i=0;i<nums.size()-2;i++)
        {
            for(int j=i+1;j<nums.size()-1;j++)
            {
                for(int k=j+1;k<nums.size();k++)
                {
                    if(nums[i]+nums[k]+nums[j]==0)
                    {
                        vector<int> tp;
                        int a=(nums[i]<nums[j]?nums[i]:nums[j])<nums[k]?(nums[i]<nums[j]?nums[i]:nums[j]):nums[k];//放最小的元素
                        int b=(nums[i]>nums[j]?nums[i]:nums[j])>nums[k]?(nums[i]>nums[j]?nums[i]:nums[j]):nums[k];//放最大的元素
                        int c=0-a-b;
                        tp.push_back(a);
                        tp.push_back(c);
                        tp.push_back(b);
                        ret.insert(tp);
                    }
                }
            }
        }
        for(auto it:ret)
        {
            res.push_back(it);
        }
        return res;
    }
};

3 思路2---排序加双指针

  • 第一步将整个数组排序,如下图。
  • 从左侧开始,选定第一个数为定值比如下面的-4,然后左右指针分别指向对应位置如下图,是不是很像快排。
  • 定义的左右和定值相加
    • 如果等于0,记录下三个值
    • 如果小于0,左指针右移动
    • 如果大于0,右指针左移
  • 然后定值右移,重复这个步骤

下面先看看整体的代码,随后图解整个代码流程以及如何处理重复的情况

c++版本

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;
    }
};

一次循环的图解


如果有重复数,怎么去重的呢。如果测试数据为[-2,0,0,2,2]。


我想起在参考招聘要求的时候有句话是熟悉c/c++,java之一,同时了解python等脚本更好,所以在此放上python的方法。

python版本

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:

        nums.sort()
        n = len(nums)#获取列表长度
        res = []#存放结果

        for i in range(n):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            num1 = nums[i]#取得定值
            if num1 > 0:
                break
            #定义双指针初始状态
            j = i + 1
            k = n - 1
            while j < k:
                total = num1 + nums[j] + nums[k]
                if total == 0:
                    res.append((num1, nums[j], nums[k]))
                    j += 1
                    while nums[j] == nums[j-1] and j < k:
                        j += 1
                    k -= 1
                    while nums[k] == nums[k+1] and j < k:
                        k -= 1
                elif total > 0:
                    k -= 1
                    while nums[k] == nums[k+1] and j < k:
                        k -= 1
                else:
                    j += 1
                    while nums[j] == nums[j-1] and j < k:
                        j += 1
        return res

4 总结

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

5 结尾

希望读者和咱一起一步一个脚印去把基础知识打牢固。如果读者发现有什么错误或者不太好的地方,欢迎私我,我会及时修改。如果觉得不错或者方便手机上查看可以在下面公众号温故复习哟!

原文地址:https://www.cnblogs.com/lanjianhappy/p/12142024.html

时间: 2024-11-08 07:03:42

[leetcode数组系列]2三数之和的相关文章

[LeetCode] 3Sum Closest 最近三数之和

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {-1 2

每天AC系列(一):三数之和

1 题目 LeetCode第15题,难度中等,题目描述: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. 2 解法 什么也不管先来个O(n3): for(int i=0;i<nums.length;++i) { for(int j=i+1;j<nums.length;++j) { for(int k=j+1;k<nums.length;

LeetCode 15. 3Sum(三数之和)

Given an array S of n integers, are there elements a, b, c in S 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. For example, given array S = [-1,

LeetCode第15题 三数之和

/* 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]*/ /* 思路: 首先想到的肯定是穷举,时间复杂度为O(n^3) , 但如果使用这种方法,也实在称不上算法题了,果不其然,超时. [

15.三数之和——LeetCode

1 package threesum; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.List; 6 7 /** 8 * 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 9 * 注意:答案中不可以包含重复的三元组 10 * 11 * 主要的思想:如果采用暴力法的话,时间复杂

LeetCode第十六题-找出数组中三数之和最接近目标值的答案

3Sum Closest 问题简介: 给定n个整数的数组nums和整数目标,在nums中找到三个整数,使得总和最接近目标,返回三个整数的总和,可以假设每个输入都只有一个解决方案 举例: 给定数组:nums=[-1, 2, 1, -4], 目标值:target = 1. 最接近目标值的答案是2 (-1 + 2 + 1 = 2). 解法一: 与上一道题类似,这次要求的是三数之和与目标值的差值最小值,可以定义一个变量来记录这个差值 思路就是想先定义一个最接近的值默认取前三个数的合,然后将数组排序后 小

leetcode 三数之和

题目: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. 题目分析: 利用循环,使得三数之和为0.分别令i,l,r为三个数,i作为外循环,遍历数组.主要难点在于不重复 参考:https://leetcode.com/problems/3sum/discuss/147561/Python-tm 代码(python): 原文地址:https://ww

LeetCode:最接近的三数之和【16】

LeetCode:最接近的三数之和[16] 题目描述 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一答案. 例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2). 题目分析 这道题就是三数之和问题的一种变形. 三数之和问题的求解策略是将三指针变为双指针问题

【LeetCode每天一题】3Sum(三数之和)

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 =