leetcode 15 三数之和

之前没有把三数之和整理,今天把two sum,three sum, four sum 都发出来

我的第一感觉就是:仿照two sum的哈希方法,表示nums,然后双重循环,时间复杂度O(n2),然而由于leetcode挂掉,我的代码丢了,如果能找回来再贴:

 

先贴优化过的解:

C++解法二:

 1 class Solution {
 2 public:
 3     vector<vector<int>> threeSum(vector<int>& nums) {
 4         vector<vector<int>> res;
 5         //对数组进行排序,便于节省搜索
 6         sort(nums.begin(),nums.end());
 7         //对不成立的情况实现做出判断节省时间
 8         if(nums.empty()||nums.back()<0||nums.front()>0) return {};
 9         //对数组从小到大进行遍历,遍历到大于0的数就停止
10        for(int k=0;k<nums.size();k++){//先遍历找到要fix的那个数
11            if(nums[k]>0) break;
12            if(k>0 && nums[k]==nums[k-1]) continue;//短路表达式
13            int target=0-nums[k];
14            int i=k+1,j=nums.size()-1;
15            while(i<j){
16                if(nums[i]+nums[j]==target){
17                    res.push_back({nums[k],nums[i],nums[j]});
18                    while(i<j && nums[i]==nums[i+1]) ++i;//短路表达式
19                    while(i<j && nums[j]==nums[j-1]) --j;//短路表达式
20                    ++i;--j;
21                }else if(nums[i]+nums[j]<target){
22                    ++i;
23                }else {
24                    --j;
25                }
26            }
27         }
28         return res;
29     }
30 };

思路如下:

 

 

由于需要找三个数,而且之和为0,必然有正有负,首先对nums进行排序,降低搜索的复杂度

并且首先对不成立的情况实现做出判断节省时间。

然后,思想是先fix一个数nums[k],然后查找另外两个数,使得他俩的和为0-nums[k];

先从头,对所有的不大于零的数进行遍历,并且对一个数只fix一次(防止重复答案出现);这是因为如果要找到三个和为0 的数,除了000这种情况,最左边的数一定为负数,所以只需遍历fix所有不大于0的数即可

然后,从nums[k]之后的数组的首尾两端分别遍历找另外两个元素,如下图:

 

 可知i和j搜索次数加起来为剩下的数组长度;总得时间O(n2)级别。

除此之外,还要注意,在找到正确答案之后,要跳过和nums[i]和nums[j]两个数相等的数,因为这些数会导致答案重复,所以先行跳过避免重复。

posted @ 2019-01-18 21:35  Joel_Wang  阅读(334)  评论(0编辑  收藏  举报