「每日刷题,快乐学习」18.四数之和

1. 题目

来源:力扣(LeetCode)
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。

2. 解题思路

  • 四个数求和去与目标值判断比较
  • 正常思路4重循环
  • 排除重复求和问题,先进行排序,用srot()即可
  • 避免暴力循环,采用两层外循环+双指针方式
    由以上思考得到一般思路:
  1. 先对数组排序,升序排列。在得到的数组中,从左开始两层嵌套循环定义前两个数A和B;
  2. 从接下剩下的数中,定义一个遍历,前后指针去获取两个数C和D;
  3. 判断A+B+C+D的值,若比目标值大,尾指针前移,若比目标指针销,前指针后移,若相等,则保存A B C D 的值,两个指针均往里靠;
  4. 遍历过程中由于是前后指针,当相遇的时候退出;依次执行遍历之外的循环。

【注意:】排序之后,数组中存在重复数字,查找答案是可能存在相同的答案,只要保证A,B,C ,D四个数字在每次计算得到目标结果后,不与上次相同即可,但是ABCD四个数是可以相等的即A=B=C=D。

【优化:】在排序之后,数字从小到大,在一二层循环中可增加判断初始的一二个数和最尾段的和,若该和小于目标值,则该层循环结束,进入下一层循环,即增加第1或第2个数字的大小。更快接近目标值。

3. 参考代码

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
    // 标准库排序方法
    std::sort(nums.begin(), nums.end());
    std::vector<std::vector<int>> res;
    if (nums.size()<4)
        return res;
    
    // 三重循环
    // 第一重代表第一个数
    for (size_t i = 0; i < nums.size()-3; i++)
    {
        int num1;
        if (i>0&&nums[i]==nums[i-1])
            continue;
        else
            num1 = nums[i];
        // 第一重代表第二个数
        for (size_t j = i+1; j < nums.size()-2; j++)
        {
            int num2;
            if (j > i+1 && nums[j]==nums[j-1])
                continue;
            else
                num2 = nums[j];
            // 第三重循环选择移动 第3个数或者第4个数
            size_t k = j+1;
            size_t w = nums.size()-1;
            while (k<w)
            {
                int num3 = nums[k];
                int num4 = nums[w];
                int temp =  num3 +num4;
                if ((target -num1 - num2) > temp)
                {    
                    k = k+1;
                    continue;
                }
                else if ((target  -num1 - num2) < temp)
                {
                    w = w-1;
                    continue;
                }    
                else                
                {
                    std::vector<int> re={num1 , num2 , num3 ,num4};
                    res.push_back(re);
                    w--;
                    while (k<w && (nums[++k] == nums[k-1])){}
                    continue;
                }
            }
        }
    }
    return res;
    }
};
上一篇:正则表达式常用方法


下一篇:4.匿名函数