leetcode_18四数之和
一、题目描述
二、想法
题目有几个关键点需要注意,第一个是,得到的结果,四个数字的组合不能重复。第二个是,同一个组合里面,数字可以重复
本来我的想法是先做遍历,然后对结果进行一个排序。
但是想了想这样的话可能会造成算法的低效。
所以较好的一个结果是先排序,然后固定第一个数字和第二个数字,对三四数字进行一个遍历,得到结果。
下面是别人的一个较好的算法过程
三、代码
class Solution { public: vector<vector<int>> fourSum(vector<int>& nums, int target) { vector<vector<int>> result; int length = nums.size(); if(length>=4) { sort(nums.begin(), nums.end()); //排序方便后续的遍历,升序排列 int first,second,third, fourth; for(first=0; first<length-3; first++) { if(first>0 && nums[first]==nums[first-1]) continue; //确保遍历过程中第一个数字被改变 for(second=first+1; second<length-2; second++) { if(second>first+1 && nums[second]==nums[second-1]) continue;//确保第二个数字被改变 third = second+1; fourth = length-1; int sum_one_two = nums[first]+nums[second]; while(third<fourth) //没有撞到一起的时候 { if(sum_one_two - target < -(nums[third]+nums[fourth]))//third的数字太小了 third++; else if(sum_one_two -target > -(nums[third] + nums[fourth]))//fourth太大了 fourth--; else //等于target { result.push_back({nums[first], nums[second], nums[third], nums[fourth]}); while(third<fourth && nums[third]==nums[third+1]) //开始遍历third,确保代表的数字不会重复 third++; while(third<fourth && nums[fourth]==nums[fourth-1])//开始遍历fourth,确保代表的数字不会重复 fourth--; third++; fourth--; } } } } } return result; } };
四、总结
这是一种双指针解法。
有以下几点需要我学习:
1、采用自带的sort算法排序,复杂度较低
2、排除同一个位置的重复解,而不是不能有重复
3、采用了双指针包夹,更快速,将复杂度从O^4降低到O^3。
五、参考链接
[1] https://leetcode-cn.com/problems/4sum/solution/shuang-zhi-zhen-jie-fa-can-zhao-san-shu-zhi-he-ge-/
纵一苇之所如,临万顷之茫然。