C++实现LeetCode(18.四数之和)

 更新时间:2021年07月13日 10:06:50   作者:Grandyang  
这篇文章主要介绍了C++实现LeetCode(18.四数之和),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

[LeetCode] 18. 4Sum 四数之和

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:

  • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, abcd)
  • The solution set must not contain duplicate quadruplets.

    For example, given array S = {1 0 -1 0 -2 2}, and target = 0.

A solution set is:
(-1,  0, 0, 1)
(-2, -1, 1, 2)
(-2,  0, 0, 2)

LeetCode 中关于数字之和还有其他几道,分别是 Two Sum ,3Sum ,3Sum Closest,虽然难度在递增,但是整体的套路都是一样的,在这里为了避免重复项,我们使用了 STL 中的 TreeSet,其特点是不能有重复,如果新加入的数在 TreeSet 中原本就存在的话,插入操作就会失败,这样能很好的避免的重复项的存在。此题的 O(n^3) 解法的思路跟 3Sum 基本没啥区别,就是多加了一层 for 循环,其他的都一样,代码如下:

解法一:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int> &nums, int target) {
        set<vector<int>> res;
        sort(nums.begin(), nums.end());
        for (int i = 0; i < int(nums.size() - 3); ++i) {
            for (int j = i + 1; j < int(nums.size() - 2); ++j) {
                if (j > i + 1 && nums[j] == nums[j - 1]) continue;
                int left = j + 1, right = nums.size() - 1;
                while (left < right) {
                    int sum = nums[i] + nums[j] + nums[left] + nums[right];
                    if (sum == target) {
                        vector<int> out{nums[i], nums[j], nums[left], nums[right]};
                        res.insert(out);
                        ++left; --right;
                    } else if (sum < target) ++left;
                    else --right;
                }
            }
        }
        return vector<vector<int>>(res.begin(), res.end());
    }
};

但是毕竟用 TreeSet 来进行去重复的处理还是有些取巧,可能在 Java 中就不能这么做,那么还是来看一种比较正统的做法吧,手动进行去重复处理。主要可以进行的有三个地方,首先在两个 for 循环下可以各放一个,因为一旦当前的数字跟上面处理过的数字相同了,那么找下来肯定还是重复的。之后就是当 sum 等于 target 的时候了,在将四个数字加入结果 res 之后,left 和 right 都需要去重复处理,分别像各自的方面遍历即可,参见代码如下:

解法二:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int> &nums, int target) {
        vector<vector<int>> res;
        int n = nums.size();
        sort(nums.begin(), nums.end());
        for (int i = 0; i < n - 3; ++i) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            for (int j = i + 1; j < n - 2; ++j) {
                if (j > i + 1 && nums[j] == nums[j - 1]) continue;
                int left = j + 1, right = n - 1;
                while (left < right) {
                    int sum = nums[i] + nums[j] + nums[left] + nums[right];
                    if (sum == target) {
                        vector<int> out{nums[i], nums[j], nums[left], nums[right]};
                        res.push_back(out);
                        while (left < right && nums[left] == nums[left + 1]) ++left;
                        while (left < right && nums[right] == nums[right - 1]) --right;
                        ++left; --right;
                    } else if (sum < target) ++left;
                    else --right;
                }
            }
        }
        return res;
    }
};

到此这篇关于C++实现LeetCode(18.四数之和)的文章就介绍到这了,更多相关C++实现四数之和内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C 语言常用方法技巧

    C 语言常用方法技巧

    本文主要介绍了C语言常用方法技巧。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-03-03
  • C语言宏定义容易认不清的盲区梳理

    C语言宏定义容易认不清的盲区梳理

    宏定义是C提供的三种预处理(宏定义、文件包含、条件编译)的其中一种,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率
    2022-09-09
  • C语言超详细讲解循环与分支语句基础

    C语言超详细讲解循环与分支语句基础

    各位小伙伴们,今天给大家带来的是循环与分支语句,本篇将会向大家介绍这些语句的格式和使用的基本方法,感兴趣的朋友来看看吧
    2022-04-04
  • C++关于类结构体大小和构造顺序,析构顺序的测试详解

    C++关于类结构体大小和构造顺序,析构顺序的测试详解

    这篇文章主要介绍了C++类结构体大小和构造顺序,析构顺序的测试,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • C语言开发实现贪吃蛇游戏

    C语言开发实现贪吃蛇游戏

    这篇文章主要为大家详细介绍了C语言开发实现贪吃蛇游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • C语言实现英文文本词频统计

    C语言实现英文文本词频统计

    这篇文章主要为大家详细介绍了C语言实现英文文本词频统计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • 一篇文章带你掌握C++虚函数的来龙去脉

    一篇文章带你掌握C++虚函数的来龙去脉

    虚函数主要通过V-Table虚函数表来实现,该表主要包含一个类的虚函数的地址表,可解决继承、覆盖的问题,下面这篇文章主要给大家介绍了如何通过一篇文章带你掌握C++虚函数的来龙去脉,需要的朋友可以参考下
    2022-10-10
  • C语言实现扫雷游戏源代码

    C语言实现扫雷游戏源代码

    这篇文章主要为大家详细介绍了C语言实现扫雷游戏源代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03
  • 聊聊C语言中sizeof运算符的一个陷阱

    聊聊C语言中sizeof运算符的一个陷阱

    在C语言中,sizeof()是一个判断数据类型或者表达式长度的运算符,下面这篇文章主要给大家介绍了关于C语言中sizeof运算符的一个陷阱的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • ros项目调试:vscode下配置开发ROS项目的详细教程

    ros项目调试:vscode下配置开发ROS项目的详细教程

    这篇文章主要介绍了ros项目调试:vscode下配置开发ROS项目,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08

最新评论