leetcode No.15-16 三数之和相关问题
Posted 随煜而安
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode No.15-16 三数之和相关问题相关的知识,希望对你有一定的参考价值。
leetcode 15. 三数之和
题目
链接:https://leetcode-cn.com/problems/3sum
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
C++代码
首先最直接的解法显然是暴力循环,将所有可能的情况都遍历一遍。
这样所需要嵌套三个for循环,因此时间复杂度O(N3),显然无法接受。
如何优化呢?我没有思路,考虑先将问题简化。
可以对给定数组进行排序,变为有序数组,而排序的时间复杂度时O(NlogN),在暴力法面前不值一提,因此这个思路可行。
当数组有序时,我们就有办法处理了。问题变为了:
固定三元组中的最小数,找到 b + c = -a
既然是有序数组,我们就可以用双指针法,不断缩小可取值的范围,直到左指针l<右指针r的条件不满足
另外,需要思考下如何处理满足条件的三元组不唯一的情况,以及如何去重。
class Solution
public:
vector<vector<int>> threeSum(vector<int>& nums)
int target;
vector<vector<int>> ans;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++)
if (i > 0 && nums[i] == nums[i - 1]) continue;
if ((target = nums[i]) > 0) break;
int l = i + 1, r = nums.size() - 1;
while (l < r)
if (nums[l] + nums[r] + target < 0) ++l;
else if (nums[l] + nums[r] + target > 0) --r;
else
ans.push_back(target, nums[l], nums[r]);
++l, --r;
while (l < r && nums[l] == nums[l - 1]) ++l;
while (l < r && nums[r] == nums[r + 1]) --r;
return ans;
;
leetcode 16. 最接近的三数之和
题目
链接:https://leetcode-cn.com/problems/3sum-closest/
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
C++代码
依旧延续leetcode NO.15 三数之和
的方案,没有思路,先将问题简化,对数组nums进行排序,转为有序数组。
此时,我们依然可以使用双指针法来求解本问题。
注意思考:如何证明双指针法在逐渐收缩的过程中不会错过最优解?
class Solution
public:
int threeSumClosest(vector<int>& nums, int target)
int total_best_sum = -1;
int total_min_dict = INT_MAX;
if(nums.size() < 3)
return total_best_sum;
// 首先对数组进行排序
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size() - 2; i++)
int a = nums[i];
int residual = target - a;
int l = i + 1;
int r = nums.size() - 1;
int min_dict = INT_MAX;
int best_sum = -1;
while(l < r)
int cur_threeSum = a + nums[l] + nums[r];
int cur_dict = abs(target - cur_threeSum);
if(cur_dict == 0)
return target;
if(cur_dict < min_dict)
min_dict = cur_dict;
best_sum = cur_threeSum;
if(target - cur_threeSum > 0)
l++;
else
r--;
// 结束了a = nums[i]时最优三元组的寻找,判断是否为总体最优
if(min_dict < total_min_dict)
total_min_dict = min_dict;
total_best_sum = best_sum;
return total_best_sum;
;
执行用时: 4 ms, 在所有 C++ 提交中击败了 99.46% 的用户
内存消耗: 12.2 MB, 在所有 C++ 提交中击败了 5.14% 的用户
以上是关于leetcode No.15-16 三数之和相关问题的主要内容,如果未能解决你的问题,请参考以下文章