LeetCode 两数之和,三数之和,最接近的三数之和,四数之和(C++)

这篇博客详细介绍了如何使用C++解决LeetCode上的四道经典题目:两数之和、三数之和、最接近的三数之和以及四数之和。解题策略包括利用哈希映射、排序及双指针技巧找到满足条件的数对或数组。每道题都提供了问题描述、解题思路、代码实现和运行截图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 两数之和

问题描述

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

解题思路

使用map来存储容器中的元素和数组下标,判断target - nums[i]是否在map中,如果不在,返回{},如果在判断元素nums[i]数组下标的和nums[target - nums[i]]的数组下标是否一致,只有在不一致时才符合题意。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

代码实现

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        //数组元素个数多于3个,数组中没有重复的数字
        // 数组只有两个数,数组中可能有重复的数字
        map<int, int> iimap;
        int j = 0;
        for(auto& i : nums)
            iimap[i] = j++;
        for(int i = 0; i < nums.size(); i++){
            if(iimap.find(target - nums[i]) != iimap.end() and iimap[target - nums[i]] != i){
                return {i, iimap[target - nums[i]]};
            }
        }
        return {};
    }
};

在这里插入图片描述

2. 三数之和

问题描述

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

注意: 答案中不可以包含重复的三元组。

示例:

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

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

解题思路

  • 为避免出现重复读取,可将数组排序后再找符合题意的三元组。出现连续相等的元素,直接跳过。
  • 使用双指针的方法,从左只有每次固定一个元素,再在其元素后用两个指针寻找两个元素和为其固定元素负值即可满足题意。
  • 双指针的开始位置是:左边指针指向固定元素的后一个位置;右指针指向元素最右边。如果两个指针指向的元素和大于固定值的负值,右指针减一;小于固定值的负值,左指针加一;直到相等,压入二维数组中。

代码实现

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n = nums.size();
        sort(nums.begin(), nums.end());
        vector<vector<int>> ans;
        for(int first = 0; first < n; first++){
            if(first > 0 and nums[first] == nums[first - 1])
                continue;
            int third = n - 1; //将此行代码放到下面的for循环里面 就会超时
            int target = -nums[first];
            for(int second = first + 1; second < n; second++){
                if(second > first + 1 and nums[second] == nums[second - 1])
                    continue;
                while(second < third and nums[second] + nums[third] > target){
                    third--;
                }
                if(second == third)
                    break;
                if(nums[second] + nums[third] == target){
                    ans.push_back({nums[first], nums[second], nums[third]});
                }
            }
        }
        return ans;
    }
};

运行截图

在这里插入图片描述

3、最接近的三数之和

问题描述

给定一个包括n个整数的数组 nums和 一个目标值target。找出 nums 中的三个整数,使得它们的和与 target最接近。返回这三个数的和。假定每组输入只存在唯一答案。

示例:

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

提示:

3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4

解题思路

使用上一题“三个数之和为零”的双指针法。将数组中元素排序,从左到右每次固定一个元素,再计算包括其元素与其后面的3个元素和。三元素和与target值相比较,最后返回其绝对值最小的三元组的和。

代码实现

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        if(nums.size() == 3)
            return accumulate(nums.begin(), nums.end(), 0);
        int ans = 0;
        int n = nums.size();
        sort(nums.begin(), nums.end());
        int minnum = INT_MAX, tmp = 0;
        for(int first = 0; first < n; first++){
            int second = first + 1, third = n - 1;
            while(second < third){
                tmp = nums[first] + nums[second] + nums[third];
                if(tmp == target)
                    return target;
                if(abs(tmp - target) < minnum){
                    minnum = abs(tmp - target);
                    ans = tmp;
                }
                if(tmp > target)
                    third--;
                else
                    second++;
            }                    
        }
        return ans;
    }
};

运行截图在这里插入图片描述

4、四数之和

问题描述

给定一个包含n个整数的数组nums和一个目标值 target,判断nums中是否存在四个元素a,b,cd ,使得a + b + c + d 的值与target相等?找出所有满足条件且不重复的四元组。

注意:

答案中不可以包含重复的四元组。

示例:

给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

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

解题思路

首先将序列从小到大排序,依次从左只有固定每一个元素,其余的元素按照求三数之和的方法即可。

代码实现

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        int n = nums.size(); 
        vector<vector<int> > ans;
        sort(nums.begin(), nums.end());
        for(int first = 0; first < n; first++){
            if(first > 0 and nums[first] == nums[first - 1])
                continue;
            for(int second = first + 1; second < n; second++){
                int tar = target - (nums[first] + nums[second]);
                if(second > first + 1 and nums[second] == nums[second - 1])
                    continue;
                int fourth = n - 1;
                for(int third = second + 1; third < fourth; third++){
                    if(third > second + 1 and nums[third] == nums[third - 1])
                        continue;
                    while(third < fourth and nums[third] + nums[fourth] > tar)
                        fourth--;
                    if(third == fourth)
                        break;
                    if(nums[third] + nums[fourth] == tar)
                        ans.push_back({nums[first], nums[second], nums[third], nums[fourth]});
                }
            }
        }
        return ans;     
    }
};

运行截图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值