四数之和
参考三数之和思路,双指针法,设置left,right,与三指针法不同,这里需要两个for遍历i和j(一共四个变量)
代码随想录提醒:
双指针法将时间复杂度:O(n^2)的解法优化为 O(n)的解法。也就是降一个数量级,题目如下:
- 27.移除元素(opens new window)
- 15.三数之和(opens new window)
- 18.四数之和
-
链表相关双指针题目:
- 206.反转链表(opens new window)
- 19.删除链表的倒数第N个节点(opens new window)
- 面试题 02.07. 链表相交(opens new window)
- 142题.环形链表II
- 有很多易错,见注释
- p.s.理解整数溢出:【C++】整型溢出问题_c++整数溢出怎么处理-CSDN博客
- Java中int和long数据类型转换及溢出问题_long转int溢出-CSDN博客
-
class Solution { public: vector<vector<int>> fourSum(vector<int>& nums, int target) { int i,j,left,right; vector<vector<int>> result; sort(nums.begin(),nums.end()); if(nums.size()<4){ return result; } for(i = 0;i<nums.size()-3;i++){ if (nums[i] > target && nums[i] >= 0) {//不用继续(没考虑) break; } if(i>0 && nums[i] == nums[i-1]){ continue; } for(j = i+1;j<nums.size()-2;j++){ if (nums[j] + nums[i] > target && nums[j] + nums[i] >= 0) { break; } // if(j>1 && nums[j] == nums[j-1]){//有可能只是i和j同了 if(j>i+1 && nums[j] == nums[j-1]){ continue; } left = j+1; right = nums.size()-1; while(left<right){ //int -2147483648~2147483647 //int 约2*10^10-->long if((long)nums[i]+nums[j]+nums[left]+nums[right]>target){ right--; }else if((long)nums[i]+nums[j]+nums[left]+nums[right]<target){ left++; }else{ result.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]}); // while(nums[left]!=nums[left-1]){ // left++; // } // while(right!=nums.size() && nums[right]!=nums[right+1]){ // right--; // } // while(left<right && nums[left]==nums[left-1]){ while(left<right && nums[left]==nums[left+1]){//这里应该是把left移到最右边,即和右边比,right 同理 left++; } while(left<right && nums[right]==nums[right-1]){// right--; } left++; right--;//记得什么条件下进行什么操作 } } } } return result; } };