力扣 题目18-- 四数之和
题目
题解
思路:之前做过三数之和 ,那么我们能不能把四数转换成三数呢?
三数
nums[left] + nums[i] + nums[right]==0
四数(这里i我们可以在三数中多加一层循环从左到右 那么此时防止重复i应该从j+1开始 nums[j]也可能重复需要判断)
nums[left] + nums[i]+nums[j] + nums[right]==target
转换一下
nums[left] + nums[i] + nums[right]==target-nums[j]
那么我们改一下条件就能交了
但是我们会发现报错 超过了int的范围
于是我们需要改成
nums[left] + nums[i] ==target-nums[j]-nums[right]
提交
虽然成功了 但是有点不如人意 肯定是在遍历的时候存在一些问题
通过观察可以发现 如果
nums[j] + nums[nums.size() - 1] < target - nums[nums.size() - 3] - nums[nums.size() - 2]
即此轮最大值都小于target 那么就不会其他可能性也不会和target相等 直接跳出即可
同理 此轮最小值都大于target 那么就不会其他可能性也不会和target相等 直接跳出即可
然后我们在两次循环都判断一下这种可能性(别忘记下标出界)即可
可以看见 虽然还是不尽人意但是好多了
代码
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 class Solution { 6 public: 7 vector<vector<int>> fourSum(vector<int>& nums, int target) { 8 vector<vector<int>> four; 9 sort(nums.begin(), nums.end()); 10 //如果长度小于4 直接返回 11 if (nums.size() < 4) { 12 return four; 13 } 14 for (int j = 0; j < nums.size() - 1; j++) { 15 //如果nums[j]重复直接跳出 16 if (j > 0 && nums[j] == nums[j - 1]) { 17 continue; 18 } 19 //下面同一使用这种比较方式 防止 20 //如果最大值都小于target 那么此轮就没有答案跳出 21 if (j < (nums.size() - 3) && nums[j] + nums[nums.size() - 1] < target - nums[nums.size() - 3] - nums[nums.size() - 2]) { 22 continue; 23 } 24 //如果最小值都大于target 那么此轮就没有答案跳出 25 if (j<(nums.size() - 3) && nums[j] + nums[j + 1] > target - nums[j + 3] - nums[j + 2]) { 26 continue; 27 } 28 for (int i = j + 1; i < nums.size(); i++) { 29 //防止nums[i]重复 直接跳出 30 if (i > j + 1 && nums[i] == nums[i - 1]) { 31 continue; 32 } 33 int left = i + 1; 34 int right = nums.size() - 1; 35 //如果最小值都大于target 那么此轮就没有答案跳出 36 if (i < nums.size() - 2 && nums[left] + nums[i] > target - nums[j] - nums[left + 1]) { 37 break; 38 } 39 //如果最大值都小于target 那么此轮就没有答案跳出 40 if (right > 1 && nums[right - 1] + nums[i] < target - nums[j] - nums[right]) { 41 continue; 42 } 43 while (left < right) 44 { 45 if (nums[left] + nums[i] == target - nums[j] - nums[right]) { 46 four.push_back({ nums[left],nums[i],nums[right],nums[j] }); 47 while (left < right && nums[left] == nums[left + 1]) { 48 left = left + 1; 49 } 50 while (left < right && nums[right] == nums[right - 1]) { 51 right = right - 1; 52 } 53 left = left + 1; 54 right = right - 1; 55 } 56 else if (nums[i] + nums[left] > target - nums[j] - nums[right]) { 57 right = right - 1; 58 } 59 else { 60 left = left + 1; 61 } 62 } 63 } 64 } 65 return four; 66 } 67 }; 68 69 int main() { 70 Solution sol; 71 vector<int> nums = { 1,0,-1,0,-2,2 }; 72 vector<vector<int>>num = sol.fourSum(nums,0); 73 for (int i = 0; i < num.size(); i++) { 74 cout << "num[" << i << "]" << "[0]=" << num[i][0] << endl; 75 cout << "num[" << i << "]" << "[1]=" << num[i][1] << endl; 76 cout << "num[" << i << "]" << "[2]=" << num[i][2] << endl; 77 cout << "num[" << i << "]" << "[3]=" << num[i][3] << endl; 78 } 79 }