3Sum Closest
来源:互联网 发布:软件管理360 编辑:程序博客网 时间:2024/05/16 06:53
题目
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).
思路一
先遍历所有的可能的三元组,再计算和最接近target的三元组和。
class Solution {public: int threeSumClosest(vector<int> &num, int target) { // Start typing your C/C++ solution below // DO NOT write int main() function vector<vector<int>> result; if(num.size()<3) return 0; sort(num.begin(),num.end()); vector<int> myvec; mythree(result,myvec,num,0,0); int res = 0; int min = 0; for(int i=0;i<result.size();i++) { int tmp = result[i][0]+result[i][1]+result[i][2]; if(i==0) { min = abs(tmp-target); res = tmp; } if(abs(tmp-target)<min) { min = abs(tmp-target); res = tmp; } } return res; } void mythree(vector<vector<int>> &result, vector<int> &vec, vector<int> &num, int cur, int sum) { if(vec.size()==3) { result.push_back(vec); return ; } if(vec.size()>3 || cur==num.size()) return ; for(int i=cur;i<num.size();i++) { if(i>cur && num[i]==num[i-1]) continue; vec.push_back(num[i]); mythree(result,vec,num,i+1,sum+num[i]); vec.pop_back(); } } };
上述代码的缺点是 需要实现存储所有的三元组,所以 空间复杂度比较高。在测试大数据是,会出现 Run Status: Output Limit Exceeded
其实上述代码没必要存储所有的三元组。于是有了思路二。
思路二
class Solution {public: int threeSumClosest(vector<int> &num, int target) { // Start typing your C/C++ solution below // DO NOT write int main() function if(num.size()<3) return 0; sort(num.begin(),num.end()); vector<int> myvec; int min = abs(num[0]+num[1]+num[2]-target); int res = num[0]+num[1]+num[2]; mythree(myvec,num,0,min,res,target); return res; } void mythree(vector<int> &vec, vector<int> &num, int cur, int &min, int &res, int target) { if(vec.size()==3) { int tmp = vec[0]+vec[1]+vec[2]; if(abs(tmp-target)<min) { min = abs(tmp-target); res = tmp; } return ; } if(vec.size()>3 || cur==num.size()) return ; for(int i=cur;i<num.size();i++) { if(i>cur && num[i]==num[i-1]) continue; vec.push_back(num[i]); mythree(vec,num,i+1,min,res,target); vec.pop_back(); } } };
该方法可以通过小数据集,但是对于大数据集,又出现了 Run Status: Time Limit Exceeded
所以这种 基于全遍历的方法 是会超时的。
同时我们考虑到:target=5,当前 min =3,即
(1)若tmp<target ,则tmp=2 , 我们知道往后遍历时,只要tmp<target,则min是不断减小的;
(2)若tmp>target ,则tmp=8 , 我们知道往后遍历时,只要tmp>target,则min是不断增加的;
所以可以剪枝部分不符合条件的遍历。
class Solution {public: int threeSumClosest(vector<int> &num, int target) { // Start typing your C/C++ solution below // DO NOT write int main() function if(num.size()<3) return 0; sort(num.begin(),num.end()); vector<int> myvec; int min = abs(num[0]+num[1]+num[2]-target); int res = num[0]+num[1]+num[2]; mythree(myvec,num,0,min,res,target); return res; } void mythree(vector<int> &vec, vector<int> &num, int cur, int &min, int &res, int target) { if(vec.size()==3) { int tmp = vec[0]+vec[1]+vec[2]; if(abs(tmp-target)<min) { min = abs(tmp-target); res = tmp; } return ; } if(vec.size()>0 && vecSum(vec)-target>min) return ; if(vec.size()>3 || cur==num.size()) return ; mythree(vec,num,cur+1,min,res,target); vec.push_back(num[cur]); mythree(vec,num,cur+1,min,res,target); vec.pop_back(); } int vecSum(vector<int> &myvec) { int sum = 0; for(int i=0;i<myvec.size();i++) sum+=myvec[i]; return sum; } };
其中 if(vec.size()>0 && vecSum(vec)-target>min) return ;
就是剪枝语句。
但是好像对于大数据,还是Run Status: Time Limit Exceeded
分析:虽然加入了剪枝,时间复杂度好像还是 O(N3) 的。
思路三
以第 i 个元素为中间点,分别向左、向右遍历,left 、 right 和 i 记录 当前三元组。
根据值与target的关系更新left和right。
class Solution {public: int threeSumClosest(vector<int> &num, int target) { // Start typing your C/C++ solution below // DO NOT write int main() function if(num.size()<3) return 0; sort(num.begin(),num.end()); int res = num[0]+num[1]+num[2]; int min = abs(target-res); for(int i=1;i<num.size()-1;i++) { int left = i-1; int right = i+1; while(left>=0 && right<num.size()) { int tmp = num[left]+num[i]+num[right]; if(tmp==target) return tmp; else if(tmp<target) { if(target-tmp<=min) { min = target-tmp; res = tmp; } right++; } else { if(tmp-target<=min) { min = tmp-target; res = tmp; } left--; } } } return res; }};
时间复杂度是O(N2) 的。
最新 java
public class Solution { public int threeSumClosest(int[] nums, int target) { if(nums == null || nums.length < 3){ return 0; } Arrays.sort(nums); int result = nums[0]+nums[1]+nums[2]; int min = Math.abs(result-target); // dfs(result, list, nums, 0, 0); for(int i=0; i<nums.length-2; i++){ // //avoid duplicate solutions if (i == 0 || nums[i] > nums[i-1]) { int start = i + 1; int end = nums.length - 1; while(start < end){ int sum = nums[i] + nums[start] + nums[end]; //case 1 if (sum == target) { return sum; //case 2 } else if (sum < target) { if(target - sum < min){ min = target - sum; result = sum; } start++; //avoid duplicate solutions while (start < end && nums[start] == nums[start - 1])start++; //case 3 } else { if(sum - target < min){ min = sum - target; result = sum; } end--; //avoid duplicate solutions while (start < end && nums[end] == nums[end + 1]) end--; } } } } return result; }}
- 3 Sum & 3 Sum Closest
- 【Leetcode】3Sum Closest (Sum)
- LeetCode: 3 Sum Closest
- 3Sum Closest
- leetcode - 3 sum closest
- leetcode 3Sum Closest
- LeetCode: 3Sum Closest
- [Leetcode]3Sum Closest
- Leetcode: 3SUM Closest
- LeetCode 3Sum Closest
- [Leetcode] 3Sum Closest
- leetcode002:3sum closest
- LeetCode : 3Sum Closest
- LeetCode 3Sum Closest
- 3Sum Closest
- 3Sum Closest
- 3Sum Closest
- [LeetCode] 3Sum Closest
- Android基于box2d开发弹弓类游戏[五]-------------发射子弹
- hdu1072 Nightmare (BFS)
- c++ Lecture 1
- Android基于box2d开发弹弓类游戏[六]-------------移动的镜头&添加目标
- 原创文章对于网站优化有怎样的重要性
- 3Sum Closest
- Memory loss: 7 tips to improve your memory
- hdu1195 Open the Lock(BFS)
- android:layout_weight和android:layout_gravity用法
- ireport+jasperreport 直接输出到打印机 普通报表 交叉报表
- CF 329A(Purification-贪心-非DLX)
- poj 1723Soldiers 带全中位数
- UVaOJ10717 - Mint
- 海量数据处理算法—Bloom Filter