1. 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:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
  • The solution set must not contain duplicate triplets.
    For example, given array S = {-1 0 1 2 -1 -4},A solution set is:(-1, 0, 1)(-1, -1, 2)

【解析】

K Sum问题是一个系列,博客 http://tech-wonderland.net/blog/summary-of-ksum-problems.html 总结得比较完整,有兴趣可以去看。

排序之后,我们就可以对数组用两个指针分别从前后两端向中间扫描了,如果是 2Sum,我们找到两个指针之和为target就OK了,那 3Sum 类似,我们可以先固定一个数,然后找另外两个数之和为第一个数的相反数就可以了。

代码不难,先看了再说。

class 3Sum{
public:void twoSum(vector<vector<int>> &ret, vector<int> &nums, int begin, int target){int l=begin;int r=nums.size()-1;while(l<r)//分别从前面和后面向中间走,从而保证最后产生的数据集一定是从小到大排序的{if(nums[l]+nums[r]+target==0){vector<int> line;line.push_back(target);line.push_back(nums[l]);line.push_back(nums[r]);ret.push_back(line);while(l<r && nums[l]==nums[l+1]) l++;//去重while(l<r && nums[r]==nums[r-1]) r--;<span style="font-family: Arial;">//去重</span>l++;r--;}else if(nums[l]+nums[r]+target<0)l++;elser--;}}vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> ret;if(nums.size()<=2)return ret;int target;sort(nums.begin(), nums.end());twoSum(ret, nums, 1, nums[0]);for(int i=1; i<nums.size()-2; i++)//注意,这里需要保证后面的数据至少有两个才可以进行下面的操作{if(nums[i]>0)break;if(nums[i]==nums[i-1])continue;elsetwoSum(ret, nums, i+1, nums[i]);}return ret;}
};

注意,对于 num[i],寻找另外两个数时,只要从 i+1 开始找就可以了。

这种写法,可以避免结果集中有重复,因为数组时排好序的,所以当一个数被放到结果集中的时候,其后面和它相等的直接被跳过。

2. 3Sum closet

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 1 -4}, and target = 1.The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
class 3SumCloset{
public:int towSumCloset(vector<int> & nums, int begin, int curData, int target){int l=begin;int r=nums.size()-1;int closet=nums[l]+nums[r]+curData;while(l<r){int tmp=nums[l]+nums[r]+curData;if(tmp==target)return tmp;else if(tmp<target){if(abs(tmp-target) < abs(closet-target))closet=tmp;while(l<r && nums[l]==nums[l+1]) l++;l++;}else{if(abs(tmp-target) < abs(closet-target))closet=tmp;while(l<r && nums[r]==nums[r-1]) r--;r--;}}return closet;}int threeSumClosest(vector<int>& nums, int target) {int closetTarget=nums[0]+nums[1]+nums[2];int twoRet;int len=nums.size();sort(nums.begin(), nums.end());for(int i=0; i<len-2; i++)//或许前面的题目这里不是重点,但在此处必须保证i后面有两个元素或以上,否则会出错{if(i>0 && nums[i]==nums[i-1])continue;twoRet=towSumCloset(nums, i+1, nums[i], target);if(twoRet==target)return target;else{if(abs(target-closetTarget) > abs(target-twoRet))closetTarget=twoRet;}}return closetTarget;}
};

3. 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, a ≤ b ≤ c ≤ d)
  • 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)

解析:

4sum问题甚至到ksum都可以用改方法一步的完善,只是,写函数时,要将4,5,6,等用参数的形式传进去就可以了

class fourSum{
public:int len;vector<int> line;//这里自己定义了line,可以减少成员函数的参数个数void TwoSum(vector<vector<int>> & ret, vector<int> & nums, int begin, int target){int l=begin;int r=len-1;while(l<r){if(nums[l]+nums[r]==target){line[2]=nums[l];line[3]=nums[r];ret.push_back(line);while(l<r && nums[l+1]==nums[l]) l++;while(l<r && nums[r]==nums[r+1]) r--;l++;r--;}   else if(nums[l]+nums[r]<target)l++;elser--;}}void ThreeSum(vector<vector<int>> & ret, vector<int> & nums, int begin, int target){for(int i=begin; i<len-2; i++){if(i>begin && nums[i]==nums[i-1])continue;line[1]=nums[i];TwoSum(ret, nums, i+1, target-nums[i]);}}vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;if(nums.size()<4)return ret;line.resize(4);len=nums.size();sort(nums.begin(), nums.end());for(int i=0; i<nums.size()-3; i++){if(i>0 && nums[i]==nums[i-1])continue; else{line[0]=nums[i];ThreeSum(ret, nums, i+1, target-nums[i]);}}return ret;}
};

更经典的解法见:http://tech-wonderland.net/blog/summary-of-ksum-problems.html

class Solution {
02 public:
03     vector< vector > findZeroSumInSortedArr(vector &num, int begin, int count, inttarget)
04     {
05         vector ret;
06         vector tuple;
07         set visited;
08         if (count == 2)
09         {
10             int i = begin, j = num.size()-1;
11             while (i < j)
12             {
13                 int sum = num[i] + num[j];
14                 if (sum == target && visited.find(num[i]) == visited.end())
15                 {
16                     tuple.clear();
17                     visited.insert(num[i]);
18                     visited.insert(num[j]);
19                     tuple.push_back(num[i]);
20                     tuple.push_back(num[j]);
21                     ret.push_back(tuple);
22                     i++; j–;
23                 }
24                 else if (sum < target)
25                 {
26                     i++;
27                 }
28                 else
29                 {
30                     j–;
31                 }
32             }
33         }
34         else
35         {
36             for (int i=begin; i<num.size(); i++)
37             {
38                 if (visited.find(num[i]) == visited.end())
39                 {
40                     visited.insert(num[i]);
41                     vector subRet = findZeroSumInSortedArr(num, i+1, count-1, target-num[i]);
42                     if (!subRet.empty())
43                     {
44                         for (int j=0; j<subRet.size(); j++)
45                         {
46                             subRet[j].insert(subRet[j].begin(), num[i]);
47                         }
48  
49                         ret.insert(ret.end(), subRet.begin(), subRet.end());
50                     }
51                 }
52             }
53         }
54  
55         return ret;
56     }
57  
58     vector threeSum(vector &num) {
59         sort(num.begin(), num.end());
60         return findZeroSumInSortedArr(num, 0, 3, 0);
61     }
62  
63     vector fourSum(vector &num, int target) {
64         sort(num.begin(), num.end());
65         return findZeroSumInSortedArr(num, 0, 4, target);
66     }
67 };

3sum、3Sum closet、 4sum相关推荐

  1. js-03--for、while、continue、break、断点调试、数组、

    文章目录 1.for 1.1 基本使用 1.2 循环退出 1.3 循环嵌套 2. while 2.1 语法 2.2 注意事项 2.3 练习 3. continue 4. break 2.4 断点调试 ...

  2. Plotly.js使用详细介绍(折线图、饼状图、点图、水平条形图、桑基图、树状图、等值线图)

    目录 0 写在前面 1 HTML代码 2 折线图 2.1 基本折线图 2.2 复杂折线图 2.2.1 轨迹 2.2.2 布局 3 饼状图 3.1 基本饼状图 3.2 饼图子图 3.3 甜甜圈图 4 点 ...

  3. 程序主动进行电话短信报警,自定义电话、短信、钉钉报警通知

    程序主动进行电话短信报警,自定义电话.短信.钉钉报警通知 一. 规则说明 这里我们要利用到阿里云的云监控的手段,有一个叫做事件监控的东西,可以通过自定义事件上传来进行监控报警. 流程: 程序发现错误 ...

  4. 使用第三方SDK(如微信、qq、快看、头条等),调用接口405 Method Not Allowed

    使用第三方SDK(如微信.qq.快看.头条等),调用接口405 Method Not Allowed 错误描述:postman请求正常,但客户端调用后接口没有反应,但返回了405错误. 解决方法:第三 ...

  5. IDEA设置单个文件、单个包、单个项目的编码格式

    IDEA设置单个文件.单个包.单个项目的编码格式 File-> Settings-> File Enclodings 选择编码格式,确定即可. 注意:此处的编码格式设定以后,该包已经存在的 ...

  6. 一分钟带你了解什么是“复杂度” 算法上的O(1)、O(n)、O(logn) 这些都是什么❓❓

    前言:在最开始学习编程的时候,打开数据结构的书,最显眼的就是排序算法,什么堆排序.希尔排序,然后旁边写着最坏复杂度.最优复杂度.平均复杂度,是一些O(n).O(logn).O(n²).这时候我脑子想起 ...

  7. etcd 笔记(05)— etcd 代码结构、各模块功能、整体架构、各模块之间的交互、请求和应答流程

    1. etcd 项目结构和功能 etcd 项目代码的目录结构如下: $ tree ├── auth ├── build ├── client ├── clientv3 ├── contrib ├── ...

  8. etcd 笔记(01)— etcd 简介、特点、应用场景、常用术语、分布式 CAP 理论、分布式原理

    1. etcd 简介 etcd 官网定义: A highly-available key value store for shared configuration and service discov ...

  9. C++ 笔记(27)— 指针变量、数组和指针、指针数组、数组指针、指针常量与常量指针

    1. 什么是指针变量? 指针变量是专门有一个变量来存放指针. int main(int argc, char *argv[]) {int a = 10;int *p = &a; //通过取地址 ...

  10. 浅显易懂 Makefile 入门 (01)— 什么是Makefile、为什么要用Makefile、Makefile规则、Makefile流程如何实现增量编译

    1. 什么是 Makefile Makefile 文件描述了 Linux 系统下 C/C++ 工程的编译规则,它用来自动化编译 C/C++ 项目.一旦写编写好 Makefile 文件,只需要一个 ma ...

最新文章

  1. 《滚动数组》---滚动数组思想,运用在动态规划当中
  2. XFire WebService demo
  3. 通过反射越过泛型检查
  4. 用状态机STATE MACHINE实现有选择的文件转换
  5. javaone_JavaOne 2012:向上,向上和向外:使用Akka扩展软件
  6. div内容居中和布局居中样式总结
  7. stackexchange.mysql_.net core使用redis基于StackExchange.Redis
  8. python三菱_三菱机器人melfarxm.ocx控件的Python使用,MelfaRxMOCX,python,用法
  9. 3.3.4.5. 日期计算
  10. interllij IDEA2017快捷键风格修改为myEclipse快捷键风格
  11. Android v1、v2、v3签名原理
  12. 矩阵转置---c语言实现
  13. win7 开WiFi共享
  14. idea启动时加载完卡住的解决办法
  15. ROS实验笔记之——VINS-Mono在l515上的实现
  16. 【转载】风控-风控策略逻辑
  17. 服务器pg信号指的是什么信号,主板的复位信号和PG信号
  18. 基于jsp的电影订票网站的设计与开发
  19. Removing the Bias of Integral Pose Regression 阅读笔记
  20. mkv转mp4,mkv转换mp4格式方法

热门文章

  1. 1996亚特兰大奥运会歌曲《Reach》铃声 1996亚特兰大奥运会歌曲...
  2. java编译点九图,Cocos2d-x3.2 Scale9Sprite点九图形式缩放图片
  3. Visual Studio创建webapi示例
  4. 如何生成具有洗钱模式的巨大金融图?
  5. 0xc0000098(0xc0000098手动修复)
  6. 中邮集团“天机网”剑指淘宝
  7. spring boot网上投票系统毕业设计源码282018
  8. 重生之学好C的第一天
  9. tensorflow中slim详解
  10. 电子邮件基本格式(MIME格式)