class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int L = nums.size();
set<vector<int>> res;//用于存放结果,set中不能含有相同的元素
sort(nums.begin(), nums.end()); //用stl sort排序
for (int i = 0; i < L - 2; ++i)
{
if (nums[i] > 0)
break;
int exp = -nums[i];
int m = i + 1;
int n = L - 1;
while (m<n)
{
int m_n = nums[m] + nums[n];
if (m_n > exp)
{
--n;
}
else if (m_n < exp)
{
++m;
}
else
{
res.insert({nums[i],nums[m],nums[n]});
++m;
--n;
}
}
}
return vector<vector<int>>(res.begin(), res.end());
}
};
第一次的思路,首先确定一个数然后使用双指针移动,确定另外两个数。比起三个循环的是强一点。
但是提交的时候,在下面这组数据时候,运行时间超出。想了半天不是很明白,要怎样优化。索性在vs下调试。
[7,-1,14,-12,-8,7,2,-15,8,8,-8,-14,-4,-5,7,9,11,-4,-15,-6,1,-14,4,3,10,-5,2,1,6,11,2,-2,-5,-7,-6,2,-15,11,-6,8,-4,2,1,-1,4,-6,-15,1,5,-15,10,14,9,-8,-6,4,-6,11,12,-15,7,-1,-9,9,-1,0,-4,-1,-12,-2,14,-9,7,0,-3,-4,1,-2,12,14,-10,0,5,14,-1,14,3,8,10,-8,8,-5,-2,6,-11,12,13,-7,-12,8,6,-13,14,-2,-5,-11,1,3,-6]
调试时候发现总共109个数,范围也不是很大,但是存在很多重复的数字,这时候就找到问题所在,程序没有对相同的数字采取更快的处理。
修改后如下:
vector<vector<int>> threeSum(vector<int> nums) {
int L = nums.size();
set<vector<int>> res;//用于存放结果,set中不能含有相同的元素
sort(nums.begin(), nums.end()); //用stl sort排序
for (int i = 0; i < L - 2; ++i)
{
if (nums[i] > 0)
break;
int exp = -nums[i];
int m = i + 1;
int n = L - 1;
while (m<n)
{
if ((nums[m] + nums[n]) > exp&&i<m&&m<n)
{
--n;
}
else if ((nums[m] + nums[n]) < exp && i<m && m<n)
{
++m;
}
else
{
res.insert({ nums[i], nums[m], nums[n] });
while (nums[m+1] == nums[m]&& m + 1 < n)
{
++m;
}
while (nums[n - 1] == nums[n] && n - 1 > m)
{
--n;
}
++m;
--n;
}
}
}
vector<vector<int>> res_(res.begin(), res.end());
return res_;
}
最后AC,但是这速度也只能排名到4%,想想哪里还能再加速。
vector<vector<int>> threeSum(vector<int> nums) {
int L = nums.size();
vector<vector<int>> res;
sort(nums.begin(), nums.end()); //用stl sort排序
int m, n;
for (int i = 0; i < L - 2; ++i)
{
if (nums[i] > 0)
break;
if (nums[i] == nums[i - 1] && i > 0)//注意排除第一个数就相同的情况
continue;
m = i + 1;
n = L - 1;
while (m<n)
{
if (nums[i] + nums[m] + nums[n] >0)
{
--n;
}
else if (nums[i] + nums[m] + nums[n] < 0)
{
++m;
}
else
{
res.push_back({ nums[i], nums[m], nums[n] });
while (nums[m + 1] == nums[m] && m < n)
{
++m;
}
while (nums[n - 1] == nums[n] && n > m)
{
--n;
}
++m;
--n;
}
}
}
return res;
}
在这次改进中,放弃使用set,还是使用vector,对于出现相同的情况,就直接用条件直接排除,这里注意三个数都要做条件排除。这样再次提交,速度达到92.1%。
如果还是要提升,可以自己定义排序函数。