3Sum 等类似题目分析

3Sum

题目描述:给定一个整数数组,找出其中的三个数之和为0的所有组合(排除相同的组合)。

分析:利用TwoSum 中两指针的思路,我们可以先将数组排序。要找到3个数之和为0,我们可以先固定一个数num[i],将i+1和len-1分别作为头指针和尾指针,当num[i]、num[i+1]与num[len-1]的和大于0时,移动尾指针;小于0时,移动头指针;等于0则找到一组数。在循环查找下一组解时,当下一个值与当前值相等会出现重复的解,此时可以跳过当前循环来去除重复。具体代码如下:

 1  vector<vector<int>> threeSum(vector<int>& nums) {
 2         sort(nums.begin(), nums.end());
 3     int len= nums.size();
 4     vector<vector<int> > res;
 5     vector<int> mid;
 6     for(int i=0;i<len-2;i++)
 7     {
 8         if (nums[i]>0) return res;
 9                 //防止出现重复
10         if (i> 0 && nums[i] == nums[i - 1]) continue;
11         int start= i+1, end = len-1;
12         while (start<end)
13         {
14             if ((nums[start] + nums[end] +nums[i])<0) start++;
15             else if ((nums[start] + nums[end] +nums[i])>0) end--;
16             else
17             {
18                 mid.push_back(nums[i]);
19                 mid.push_back(nums[start++]);
20                 mid.push_back(nums[end--]);
21                 res.push_back(mid);
22                 mid.clear();
23                                //防止出现重复
24                 while (start<end&&nums[start] == nums[start-1]) start++;
25                 while (start<end&&nums[end] == nums[end+1]) end--;
26             }
27         }
28     }
29     return res;
30     }

3Sum Closest

给定一个数组,找到三个数之和与目标值最相近,返回这个和。例如给定数组S = {-1 2 1 -4}, and target = 1.最近似目标值的是2 (-1 + 2 + 1 = 2)。

该题解法与上一题相似,每次循环要记录下sum值与目标值的差,并保存该sum值,如果sum值与目标值相等则直接返回。代码如下:

 1 int threeSumClosest(vector<int>& nums, int target) {
 2         sort(nums.begin(), nums.end());
 3     int len= nums.size();
 4     int res=0,result=0;
 5     int dist=INT_MAX;
 6     for(int i=0;i<len-2;i++)
 7     {
 8         if (i> 0 && nums[i] == nums[i - 1]) continue;
 9         int start= i+1, end = len-1;
10         while (start<end)
11         {
12             res=nums[start] + nums[end] +nums[i];
13             if (res<target)
14             {
15                 if(target-res<dist)
16                 {
17                     result=res;
18                     dist=target-res;
19                 }
20                 start++;
21                 while (start<end&&nums[start] == nums[start-1]) start++;
22             }
23             else if (res>target)
24             {
25                if(res-target<dist)
26                {
27                    result=res;
28                    dist=res-target;
29                }
30                end--;
31                while(start<end&&nums[end] == nums[end+1]) end--;
32             }
33             else
34             return res;
35         }
36     }
37     return result;
38  }

4Sum

找到数组中的四个数a,b,c,d,使得a+b+c+d=target。这与3Sum相同,只不过我们要先固定两个数,因此多了一个循环;为了比较方便,我们记sum=target-a-b,将sum与a+b比较,代码如下:

 1 vector<vector<int>> fourSum(vector<int>& nums, int target) {
 2         sort(nums.begin(), nums.end());
 3     int len= nums.size();
 4     vector<vector<int> > res;
 5     vector<int> mid;
 6     for(int i=0;i<len-3;i++)
 7     {
 8        if (i> 0 && nums[i] == nums[i - 1]) continue;
 9        for(int j=i+1;j<len-2;j++)
10        {
11            if (j>i+1 && nums[j] == nums[j - 1]) continue;
12            int start= j+1, end = len-1,sum=target-nums[i]-nums[j];
13            while(start<end)
14            {
15             if ((nums[start] + nums[end])<sum) start++;
16             else if ((nums[start] + nums[end])>sum) end--;
17             else
18             {
19                 mid.push_back(nums[i]);
20                 mid.push_back(nums[j]);
21                 mid.push_back(nums[start++]);
22                 mid.push_back(nums[end--]);
23                 res.push_back(mid);
24                 mid.clear();
25                 while (start<end&&nums[start] == nums[start-1]) start++;
26                 while (start<end&&nums[end] == nums[end+1]) end--;
27             }
28            }
29        }
30     }
31     return res;
32     }
时间: 2024-12-22 09:04:56

3Sum 等类似题目分析的相关文章

SCJP_104——题目分析(5)

18. public class Test { public static void add3(Integer i) { int val=i.intvalue(); val+=3; i=new Integer(val); } public static void main(String args[]) { Integer i=new Integer(0); add3(i); System.out.println(i.intvalue()); } } what is the result? bA.

SCJP_104——题目分析(3)

11. what is reserved words in java?A. run B. default C. implement D. import Java 中,给标识符取名的时候,不能使用关键字和保留字. 在 Java 中常用的关键字有: 1.访问控制符: public.protected.private 2.数据类型 byte.short.int.long.float.double.char.boolean 3.与类.方法有关的 new.class.extends.implements.

SCJP_104——题目分析(2)

3. public class IfTest{ public static void main(String args[]){ int x=3; int y=1; if(x=y) System.out.println("Not equal"); else System.out.println("Equal"); } } what is the result? 这一题考察的是 if 语句.if 语句的写法如下: if (boolean expression) { st

最长英文单词串题目分析

题目来源: 这是题目来源 序: 简述一下事情的经过 一天邹欣老师在群里向我提出了一个问题: "把这个题目分析一下,主要是从工程上考虑,假如50个学生提交了程序,你如何写一个测试的系统,判断对错,和测量学生程序的对错" 一.首先分析一下这道题的核心 "最长的能首尾相连的英语单词链,每个单词最多只能使用一次" 这里题目的描述有一点不明确,关于"最长",题目并没有给出详细定义. 因此可能有两种情况. 单词链中单词数最多 单词链中字符数最多 (看到这里我

对动态规划算法的理解及相关题目分析

1.对动态规划算法的理解 (1)基本思想: 动态规划算法的基本思想与分治法类似:将待求解的问题分解成若干个子问题,先求解子问题,然后从这些子问题的解中得到原问题的解.但是,与分治法不同的是,为了避免重复多次计算子问题,动态规划算法用一个表记录所有已解决的子问题的答案,不管该子问题以后是否被利用,只要它被计算过,就将其结果填入表中. (2)设计动态规划算法的步骤: ①找出最优解的性质,并刻画其结构特征 ②递归地定义最优值 ③以自底向上的方式计算最优值 ④根据计算最优值时得到的信息构造最优解 (3)

MySQL索引题目分析

1.之前看视频呢的时候,里面提到一道索引题目:假设某个表有一个联合索引(c1,c2,c3,c4)-只能使用该联合索引的c1,c2,c3部分 a.where c1=x and c2=x and c4>x and c3=x b.where c1=x and c2=x and c4=x order by c3 c.where c1=x and c4=x group by c3,c2 d.where c1=? and c5=? order by c2,c3 e.where c1=? and c2=? a

SCTF 2014 pwn题目分析

因为最近要去做ctf比赛的这一块所以就针对性的分析一下近些年的各大比赛的PWN题目.主防项目目前先搁置起来了,等比赛打完再去搞吧. 这次分析的是去年的SCTF的赛题,是我的学长们出的题,个人感觉还是很符合套路的:一道栈溢出.一道格式化字符串.一道堆溢出. pwn200 一个栈溢出. 题目给出了libc.保护只有nx. 拿到题后的基本思路就是leak出got表中函数的地址,然后拿libc算偏移算出system的地址.然后用这个地址去覆盖一个函数的got表. pwn300 一个明显的格式化字符串漏洞

二分查找总结及部分Lintcode题目分析 2

Search in a big sorted array,这个比之前的二分法模板多了一个很不同的特性,就是无法知道一个重要的条件end值,也是题目中强调的重点 The array is so big so that you can not get the length of the whole array directly~所以这里单独分析这个问题~ 一般涉及到sorted array,肯定可以的解决方法是for loop,然而for loop的复杂度是O(n),而且对于这个长度无法衡量的big

[题解+总结]NOIP历年题目分析

1.前言 迎接NOIP的到来...在这段闲暇时间,决定刷刷水题.这里只是作非常简单的一些总结. 2.NOIP2014 <1> 生活大爆炸之石头剪刀布(模拟) 这是一道考你会不会编程的题目...方法有很多,预处理输赢矩阵,或者一大堆if什么的乱搞就行了. <2> 联合权值(搜索) 简单的树上求解问题,由于只需要长度为2的链,只要能够清楚地分析出各种情况,一遍DFS直接出来:自身节点与祖父节点有一对:自身节点与兄弟节点有若干对.在计算权值的时候存在一个优化,即如果每次得到一对之后就计算