LeetCode 18. 四数之和--二分查找

    科技2022-08-09  98

    题解:好像中文的题目界面没有说明数据范围,英文的题目界面倒是说明了,,,, 如下。 也就是数据范围在200,找4个元素,200的4次方绝对超时,于是我想到可以用二分处理,200个元素,就构成了200x200=40000个两两数字和的结果,那么我们储存下结果和对应的元素下标,比如目标和为0,nums[0]+nums[1]=-2,我们再去这40000个元素中找到所有和为2的并且下标不能和0和1重复的,储存下来,这样时间复杂度为40000xlog40000,就很小,不会超时。

    AC代码

    class Solution { public: struct Node { int val,i,j; }; vector<Node>q; static int cmp(Node a1,Node a2) { return a1.val<a2.val; } vector<int>path; vector<vector<int>>pu; void fun(int val,int s,int t,vector<int>nums) { int l=0,r=q.size()-1,fin=q.size()-1; while(l<=r) { int mid=(l+r)/2; if(q[mid].val>val)//找到第一个大于目标的元素位置 { r=mid-1; fin=mid; } else l=mid+1; } for(int i=fin;i>=0;i--) { if(q[i].val<val)break; if(q[i].val==val) { //每个元素只能被使用一次,特判 if(q[i].i==s||q[i].i==t)continue; if(q[i].j==s||q[i].j==t)continue; path.clear(); path.push_back(nums[q[i].i]); path.push_back(nums[q[i].j]); path.push_back(nums[s]); path.push_back(nums[t]); sort(path.begin(),path.end()); pu.push_back(path); } } } static int cmp2(vector<int>a,vector<int>b) { for(int i=0;i<a.size();i++) { if(a[i]<b[i])return true; if(a[i]>b[i])return false; } return false; } vector<vector<int>> fourSum(vector<int>& nums, int target) { for(int i=0;i<nums.size();i++) { for(int j=i+1;j<nums.size();j++) { Node t; t.val=nums[i]+nums[j]; t.i=i,t.j=j; q.push_back(t); } } sort(q.begin(),q.end(),cmp); for(int i=0;i<q.size();i++) { int val=target-q[i].val; fun(val,q[i].i,q[i].j,nums); } sort(pu.begin(),pu.end(),cmp2); vector<vector<int>>res; if(pu.size()==0)return res; res.push_back(pu[0]); for(int i=1;i<pu.size();i++) { int n=res.size()-1; if(res[n]!=pu[i]) res.push_back(pu[i]); } return res; } };

    太难了,408ms居然只击败了5%的人,,,,leetcode大佬太多了。

    Processed: 0.013, SQL: 8