15. 3Sum、16. 3Sum Closest和18. 4Sum
15 3sum
Given an array nums
of n integers, are there elements a, b, c in nums
such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Example:
- Given array nums = [-1, 0, 1, 2, -1, -4],
- A solution set is:
- [
- [-1, 0, 1],
- [-1, -1, 2]
- ]
思考:1、想了很久,不知道怎么做。只能想到时间复杂度比较高的做法。在网上查到,这个3sum问题是比较经典的,其解法基于2sum。2sum问题是给定一个排好序的数组,问有哪些两个元素相加为
0。解法是一个下标指向第一个,另一个下标指向最后一个。
有如下结论及其规则:
一、如果num[1]+num[n]>0,那么2和n的和大于0,3和n的和也会大于0。等等。所以就没必要再去计算以最后一个为右边界的组合。考虑1,..,n-1这个范围内的组合,即移动后一个。
二、如果num[1]+num[n]<0,那么1和n-1的和,1和n-2的和也会小于0。等等。所以就没必要去计算以1为左边界的组合。考虑2,...,n这个范围内的组合,即移动前一个下标。
不断进行这个操作,最终遍历所有可能的组合,而不是每个组合。- 3sum问题可以分解成2sum。取出数组第一个元素X,在剩下的数组里找到两数之和为-X,这就是2sum问题。
- 由于c语言不支持动态添加元素,所以用c++可能更方便一些,故实现如下。ps:用c语言做了一下,一直free内存那里出问题。
- class Solution {
- public:
- vector<vector<int>> threeSum(vector<int>& nums) {
- vector<vector<int> > ans;
- int index1,index2;
- if(nums.size()<) return ans;
- sort(nums.begin(), nums.end());
- for (int i = ; i <= nums.size()-; i++) {
- if(i!= && nums[i-]==nums[i]) continue;
- index1 = i+;
- index2 = nums.size()-;
- /*if(i==0) {
- index1 = 1;
- index2 = nums.size()-1;
- }
- else if (i== nums.size()-1) {
- index1 = 0;
- index2 = nums.size()-2;
- }else {
- index1 = 0;
- index2 = nums.size()-1;
- }*/
- while(index1<index2) {
- if(nums[i]+nums[index1]+nums[index2]==) {
- int sol[] = { nums[i], nums[index1], nums[index2] };
- ans.push_back(vector<int> (sol, sol + ));
- //printf("i is %d.index1 is %d.index2 is %d.\n", i,index1,index2);
- index1++;while(nums[index1]==nums[index1-]) index1++;
- index2--;while(nums[index2]==nums[index2+]) index2--;
- }else if (nums[i]+nums[index1]+nums[index2]>) {
- index2--;
- }else {
- index1++;
- }
- }
- }
- return ans;
- }
- };
16 3sum closet
Given an array nums
of n integers and an integer target
, find three integers in nums
such that the sum is closest to target
. Return the sum of the three integers. You may assume that each input would have exactly one solution.
Example:
- Given array nums = [-1, 2, 1, -4], and target = 1.
- The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
和上面是简单变形关系,所用的原理一样。因为此次并不需要返回数组的数组,所以又用c语言来表示我的行为。
- void my_qsort(int *nums, int index1, int index2) {
- if(index1==index2) return;
- int pre,last;
- int tmp;
- pre = index1;
- for(last=index1+; last<=index2; last++) {
- if(nums[last]<nums[index1]) {
- pre++;
- tmp = nums[pre];
- nums[pre] = nums[last];
- nums[last] = tmp;
- }
- }
- tmp = nums[index1];
- nums[index1] = nums[pre];
- nums[pre] = tmp;
- if(pre==index1) {
- my_qsort(nums, index1+, index2);
- }else if(pre==index2) {
- my_qsort(nums, index1, index2-);
- }else {
- my_qsort(nums, index1, pre-);
- my_qsort(nums, pre+, index2);
- }
- }
- int threeSumClosest(int* nums, int numsSize, int target) {
- int ret,index1,index2,tmp;
- my_qsort(nums, , numsSize-);
- for(int i = ; i<numsSize; i++)
- printf("%d ", nums[i]);
- printf("\n");
- ret = nums[] + nums[] + nums[];
- for(int i=; i<=numsSize-;i++) {
- index1 = i+;
- index2 = numsSize-;
- while(index1<index2) {
- tmp = nums[i] + nums[index1] + nums[index2];
- if(tmp == target) return tmp;
- if(abs(tmp-target)<abs(ret-target)) ret = tmp;
- if(tmp>target) {
- index2--;
- }else if(tmp < target) {
- index1++;
- }
- }
- }
- return ret;
- }
18. 4Sum
Given an array nums
of n integers and an integer target
, are there elements a, b, c, and d in nums
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.
Example:
- Given array nums = [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]
- ]
思考:首先按一定顺序取前两个数,共有(n-3)*(n-2)个组合,对于剩下的两个数就用首尾指针进行移动检查。
这里我有一个小小的优化。看下line 12行的代码,如果nums[i]大于0,nums[i]>terget,那么后面的三个数一定大于0。既然后面的三个数都大于0,nums[i]加上大于的0
一定大于target。所以就没有必要再继续检查。第15行代码同理。
- class Solution {
- public:
- vector<vector<int>> fourSum(vector<int>& nums, int target) {
- vector<vector<int>> ans;
- sort(nums.begin(), nums.end());
- int len = nums.size();
- int i,j,k,l;
- for(i=; i<=len-; i++) {
- if(nums[i]>target && nums[i]>=) continue;
- if(i>= && nums[i]==nums[i-]) continue;
- for(j=i+; j<=len-; j++) {
- if(nums[i]+nums[j]>target && nums[j]>=) continue;
- if(j>=i+ && nums[j]==nums[j-]) continue;
- k = j + ;
- l = len - ;
- while(k<l) {
- if(nums[i]+nums[j]+nums[k]+nums[l]>target) {
- l--;
- }else if(nums[i]+nums[j]+nums[k]+nums[l]<target){
- k++;
- }else {
- int sol[] = { nums[i], nums[j], nums[k],nums[l] };
- ans.push_back(vector<int> (sol, sol + ));
- k++;
- while(nums[k]==nums[k-]) k++;
- l--;
- while(nums[l]==nums[l+]) l--;
- }
- }
- }
- }
- return ans;
- }
- };
15. 3Sum、16. 3Sum Closest和18. 4Sum的更多相关文章
- leetcode 1.Two Sum 、167. Two Sum II - Input array is sorted 、15. 3Sum 、16. 3Sum Closest 、 18. 4Sum 、653. Two Sum IV - Input is a BST
1.two sum 用hash来存储数值和对应的位置索引,通过target-当前值来获得需要的值,然后再hash中寻找 错误代码1: Input:[3,2,4]6Output:[0,0]Expecte ...
- LeetCode 15. 3Sum 16. 3Sum Closest 18. 4Sum
n数求和,固定n-2个数,最后两个数在连续区间内一左一右根据当前求和与目标值比较移动,如果sum<target,移动较小数,否则,移动较大数 重复数处理: 使i为左至右第一个不重复数:while ...
- 【LeetCode】18. 4Sum 四数之和
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:four sum, 4sum, 四数之和,题解,leet ...
- 1. Two Sum&&15. 3Sum&&18. 4Sum
题目: 1. Two Sum Given an array of integers, return indices of the two numbers such that they add up t ...
- [LeetCode][Python]16: 3Sum Closest
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 16: 3Sum Closesthttps://oj.leetcode.com ...
- 《LeetBook》leetcode题解(16):3Sum Closest [M]
我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...
- LeetCode 16. 3Sum Closest(最接近的三数之和)
LeetCode 16. 3Sum Closest(最接近的三数之和)
- [LeetCode] 16. 3Sum Closest 最近三数之和
Given an array nums of n integers and an integer target, find three integers in nums such that the s ...
- Leetcode 16. 3Sum Closest(指针搜索)
16. 3Sum Closest Medium 131696FavoriteShare Given an array nums of n integers and an integer target, ...
随机推荐
- F——宋飞正传(HDU3351)
题目: I’m out of stories. For years I’ve been writing stories, some rather silly, just to make simpl ...
- Java日志介绍(4)-Log4j2
Log4j2是Log4j的升级版,相比其前身Log4j 1.x提供了显著的改进,并提供了在Logback中提供的许多改进,同时修复了Logback体系结构中的一些固有问题. Log4j2的内容很多,本 ...
- Android中使用Intent的Action和Data属性实现点击按钮跳转到拨打电话和发送短信
场景 点击拨打电话按钮,跳转到拨打电话页面 点击发送短信按钮,跳转到发送短信页面 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程 ...
- Linux报错:rm: cannot remove 'xxx': Is a directory
rm: cannot remove 'xxx': Is a directory表示这个文件是无法remove移除的,因此我们不能仅使用rm来将这个文件夹进行删除,需要使用: rm -rf 命令则可以将 ...
- Premiere Pro CC2018安装教程
Premiere Pro CC2018安装教程 下载安装包:去官网下载或者百度PR2018的安装包 解压安装包后,找到Set-up.exe,右键,打开 安装的时候我们需要注册一个账号,点击“获取Ado ...
- 关于js获取元素在屏幕中的位置的方法
针对我们获取元素在页面中的位置的问题,我们还是用老师一峰老师的方法来解决吧 下面上HTML代码 <div class="left_footer"> <p data ...
- 经济学人精读笔记9:打出租out了,“飞的”时代要来了!
经济学人精读笔记9:打出租out了,"飞的"时代要来了! 标签(空格分隔): 经济学人 Part 1 Flying taxis are taking off to whisk pe ...
- tp 框架 文本编辑器 不解析HTML标签
解析 文本编辑器 空格 {$vo.content|htmlspecialchars_decode|stripslashes|html_entity_decode}
- setter&getter
let _age = 4 class Animal { construct (type){ this.type = type } get age(){ return _age } set age(va ...
- 关于vector的描述
对于有些编译器而言,使用vector<vector<int>> vec;并不能通过,必须采用vector<vector<int> >vec才可以通过.两 ...