力扣 题目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 }
点击这里!!

 

 

 

 

posted @ 2022-04-05 14:27  无聊的阿库娅  阅读(18)  评论(0编辑  收藏  举报