描述

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: The solution set must not contain duplicate quadruplets.

示例

  1. Given array S = [1, 0, -1, 0, -2, 2], and target = 0.
  2. A solution set is:
  3. [
  4. [-1, 0, 0, 1],
  5. [-2, -1, 1, 2],
  6. [-2, 0, 0, 2]
  7. ]

算法分析

难度:中

分析:给定整型数组和指定一个整型目标值,从整形数组中找出4个不同的元素,使得4个元素之和等于目标值,返回结果为所有满足上述条件的元素组合。

思路:思路可以参考3Sum,主要难度是由原先的找3个元素之和,变成了找4个元素之和。这种情况下,其实有点像解魔方:玩五阶魔方就是从五阶降到四阶,然后再从四阶降到三阶,最后再按照玩三阶魔方的方法解决问题。

最终的解法,其实就是在3阶解法的基础上,在外层再套一层4阶的循环,并做一些基础的判断,复杂度也是在3阶n²基础上*n=n³,当然,这种算法也可推广到n阶。

代码示例(C#)

  1. public IList<IList<int>> FourSum(int[] nums, int target)
  2. {
  3. List<IList<int>> res = new List<IList<int>>();
  4. if (nums.Length < 4) return res;
  5. //排序
  6. Array.Sort(nums);
  7. //4阶判断
  8. for (int i = 0; i < nums.Length - 3; i++)
  9. {
  10. //如果最近4个元素之和都大于目标值,因为数组是排序的,后续只可能更大,所以跳出循环
  11. if (nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) break;
  12. //当前元素和最后3个元素之和小于目标值即本轮最大值都小于目标值,则本轮不满足条件,跳过本轮
  13. if (nums[i] + nums[nums.Length - 1] + nums[nums.Length - 2] + nums[nums.Length - 3] < target)
  14. continue;
  15. //防止重复组合
  16. if (i > 0 && nums[i] == nums[i - 1]) continue;
  17. //3阶判断
  18. for (int j = i + 1; j < nums.Length - 2; j++)
  19. {
  20. //原理同4阶判断
  21. if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) break;
  22. if (nums[i] + nums[j] + nums[nums.Length - 1] + nums[nums.Length - 2] < target)
  23. continue;
  24. int lo = j + 1, hi = nums.Length - 1;
  25. while (lo < hi)
  26. {
  27. //已知元素 nums[i],nums[j],剩下2个元素做夹逼
  28. int sum = nums[i] + nums[j] + nums[lo] + nums[hi];
  29. if (sum == target)
  30. {
  31. res.Add(new List<int> { nums[i], nums[j], nums[lo], nums[hi] });
  32. while (lo < hi && nums[lo] == nums[lo + 1]) lo++;
  33. while (lo < hi && nums[hi] == nums[hi - 1]) hi--;
  34. lo++;
  35. hi--;
  36. }
  37. //两边夹逼
  38. else if (sum < target) lo++;
  39. else hi--;
  40. }
  41. }
  42. }
  43. return res;
  44. }

复杂度

  • 时间复杂度O (n³).
  • 空间复杂度O (1).

附录

算法题丨4Sum的更多相关文章

  1. 算法题丨Two Sum

    描述 Given an array of integers, return indices of the two numbers such that they add up to a specific ...

  2. 算法题丨3Sum

    描述 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all ...

  3. 算法题丨3Sum Closest

    描述 Given an array S of n integers, find three integers in S such that the sum is closest to a given ...

  4. 算法题丨Remove Duplicates from Sorted Array II

    描述 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? 示例 Giv ...

  5. 算法题丨Longest Consecutive Sequence

    描述 Given an unsorted array of integers, find the length of the longest consecutive elements sequence ...

  6. 算法题丨Remove Element

    描述 Given an array and a value, remove all instances of that value in-place and return the new length ...

  7. 算法题丨Move Zeroes

    描述 Given an array nums, write a function to move all 0's to the end of it while maintaining the rela ...

  8. 算法题丨Next Permutation

    描述 Implement next permutation, which rearranges numbers into the lexicographically next greater perm ...

  9. 算法题丨Remove Duplicates from Sorted Array

    描述 Given a sorted array, remove the duplicates in-place such that each element appear only once and ...

随机推荐

  1. C++学习-8

    1.注意:函数指针前面*,&都是一样的没啥实际意义,除了把实例化函数块的时候,需要指针或者引用修饰    cout << typeid(my1.show).name() <& ...

  2. 【技术】关于安卓使用禁用服务(或者是MYANDROIDTOOLS里面的禁用服务)后卡在开机页面的(或者是卡在各种页面的)

    目前会出现禁用部分服务后卡在开机页面,导致到手机数据得全部清除在网上找了很久,都没找到还原的方法只好自己开垦新方案了推测:由于格式化DATA分区后,手机可以正常开机,所以认为禁用服务的配置内容保存在D ...

  3. IIS前端页面不显示详细错误解决方法

    要想解决这个问题,有三种方法可以考虑: 1.Internet信息服务(IIS)管理器 2.Web.config文件 3. 命令行 在IIS的"错误页"右边的"编辑功能设置 ...

  4. Lintcode208 Assignment Operator Overloading (C++ Only) solution 题解

    [题目描述] Implement an assignment operator overloading method. Make sure that: The new data can be copi ...

  5. 二分查找(Java实现)

    二分查找:递归实现 public class BinarySearch { /** * @param arr 代查找的数组,需要有序 * @param left 查找区间的左界限 * @param r ...

  6. HashMap源码解析(JDK1.8)

    package java.util; import sun.misc.SharedSecrets; import java.io.IOException; import java.io.Invalid ...

  7. Java后台模拟发送http的get和post请求,并测试

    个人学习使用:谨慎参考 1 Client类 import com.thoughtworks.gauge.Step; import com.thoughtworks.gauge.Table; impor ...

  8. 利用github协作开发步骤

    项目使用IDEA开发,IDEA上可以加载很多的插件(而且下载很快),安装github插件,安装git 首先一个成员需要创建好代码库,这个代码库存放项目,所有的开发提交代码都是向这个库提交,在githu ...

  9. 基于TODO的开发方法

    之前买了一本书,叫<架构探险-从零开始写Java Web框架 >(不推荐购买-),一本标题党书籍!但是我很推崇作者写代码的方式,就是基于TODO的方式进行开发! 个人认为以基于TODO的方 ...

  10. poj2793 素数和

    题目链接:http://poj.org/problem?id=2739 #include<iostream> using namespace std; int count=0; int p ...