| class Solution { |
| public: |
| vector<int> twoSum(vector<int>& numbers, int target) { |
| vector<int> ans; |
| int n = numbers.size(); |
| int l = 0, r = n - 1; |
| while (l < r) { |
| if ((numbers[l] + numbers[r]) == target) { |
| ans.push_back(l+1), ans.push_back(r+1); |
| break; |
| } else if ((numbers[l] + numbers[r]) < target) { |
| l++; |
| } else r--; |
| } |
| return ans; |
| } |
| }; |
本题可以看作两数之和的升级版,即固定一个数不动,看另外两个数之和是否等于这个数的相反数。时间复杂度为 (枚举第一个数为 ,双指针为 )。
| class Solution { |
| public: |
| vector<vector<int>> threeSum(vector<int>& nums) { |
| sort(nums.begin(), nums.end()); |
| vector<vector<int>> ans; |
| int n = nums.size(); |
| for (int i = 0; i < n - 2; i++) { |
| int x = nums[i]; |
| if (i && x == nums[i - 1]) continue; |
| if (x + nums[i + 1] + nums[i + 2] > 0) break; |
| if (x + nums[n - 2] + nums[n - 1] < 0) continue; |
| int l = i + 1, r = n - 1; |
| while (l < r) { |
| int sum = x + nums[l] + nums[r]; |
| if (sum > 0) r--; |
| else if (sum < 0) l++; |
| else { |
| ans.push_back({x, nums[l], nums[r]}); |
| l++; |
| while (l < r && nums[l] == nums[l - 1]) l++; |
| r--; |
| while (l < r && nums[r] == nums[r + 1]) r--; |
| } |
| } |
| } |
| return ans; |
| } |
| }; |
| class Solution { |
| public: |
| int countPairs(vector<int>& nums, int target) { |
| int n = nums.size(); |
| int l = 0, r = n - 1, ans = 0; |
| sort(nums.begin(), nums.end()); |
| while (l < r) { |
| int sum = nums[l] + nums[r]; |
| if (sum >= target) { |
| r--; |
| } else if (sum < target) { |
| ans += r - l; |
| l++; |
| } |
| } |
| return ans; |
| } |
| }; |
| class Solution { |
| public: |
| int threeSumClosest(vector<int>& nums, int target) { |
| sort(nums.begin(), nums.end()); |
| int n = nums.size(), ans; |
| int MIN = 0x3f3f3f3f; |
| for (int i = 0; i < n - 2; i++) { |
| int x = nums[i]; |
| if (i && x == nums[i - 1]) continue; |
| int s = x + nums[i + 1] + nums[i + 2]; |
| if (s > target) { |
| if (s - target < MIN) { |
| MIN = s - target; |
| ans = s; |
| } |
| break; |
| } |
| |
| s = x + nums[n - 2] + nums[n - 1]; |
| if (s < target) { |
| if (target - s < MIN) { |
| MIN = target - s; |
| ans = s; |
| } |
| continue; |
| } |
| |
| int l = i + 1, r = n - 1; |
| while (l < r) { |
| s = x + nums[l] + nums[r]; |
| if (s == target) { |
| return target; |
| } else if (s > target) { |
| if (s - target < MIN) { |
| MIN = s - target; |
| ans = s; |
| } |
| r--; |
| } else { |
| if (target - s < MIN) { |
| MIN = target - s; |
| ans = s; |
| } |
| l++; |
| } |
| } |
| } |
| return ans; |
| } |
| }; |
错误解法:固定最小边
| class Solution { |
| public: |
| int triangleNumber(vector<int>& nums) { |
| int n = nums.size(), ans = 0; |
| sort(nums.begin(), nums.end()); |
| for (int i = 0; i < n - 2; i++) { |
| int x = nums[i]; |
| int l = i + 1, r = n - 1; |
| while (l < r) { |
| if (x + nums[l] > nums[r]) { |
| ans += r - l; |
| l++; |
| } else { |
| r--; |
| } |
| } |
| } |
| return ans; |
| } |
| }; |
这里错误的原因主要是,在固定最小边 时,我们的目标是使得 a + b > c,但现在 在不等号左边,也就是当 + 时,不知道是 较小造成的还是 较大造成的。固定最大边就能保证一定是左边太小造成的。
正确解法:固定最大边
| class Solution { |
| public: |
| int triangleNumber(vector<int>& nums) { |
| int n = nums.size(), ans = 0; |
| sort(nums.begin(), nums.end()); |
| for (int k = 2; k < n; k++) { |
| int l = 0, r = k - 1; |
| while (l < r) { |
| int s = nums[l] + nums[r]; |
| if (s > nums[k]) { |
| |
| |
| |
| |
| |
| |
| ans += r - l; |
| r--; |
| } else { |
| |
| |
| |
| |
| |
| l++; |
| } |
| } |
| } |
| return ans; |
| } |
| }; |
| class Solution { |
| public: |
| vector<vector<int>> fourSum(vector<int>& nums, int target) { |
| sort(nums.begin(), nums.end()); |
| int n = nums.size(); |
| vector<vector<int>> ans; |
| for (int i = 0; i < n - 3; i++) { |
| long long x = nums[i]; |
| if (i && x == nums[i - 1]) continue; |
| if (x + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) break; |
| if (x + nums[n - 1] + nums[n - 2] + nums[n - 3] < target) continue; |
| for (int j = i + 1; j < n - 2; j++) { |
| int y = nums[j]; |
| if (j > i + 1 && y == nums[j - 1]) continue; |
| if (x + y + nums[j + 1] + nums[j + 2] > target) break; |
| if (x + y + nums[n - 2] + nums[n - 1] < target) continue; |
| int l = j + 1, r = n - 1; |
| while (l < r) { |
| long long s = x + y + nums[l] + nums[r]; |
| if (s > target) r--; |
| else if (s < target) l++; |
| else { |
| ans.push_back({(int)x, (int)y, nums[l], nums[r]}); |
| l++; |
| while (l < n && nums[l] == nums[l - 1]) l++; |
| r--; |
| while (r > j && nums[r] == nums[r + 1]) r--; |
| } |
| } |
| } |
| } |
| return ans; |
| } |
| }; |
哪边的木板短,就把哪边的木板去掉。(在中间的木板比短木板长或比短木板短都无法更新 )
| class Solution { |
| public: |
| int maxArea(vector<int>& h) { |
| int n = h.size(); |
| int ans = 0; |
| int l = 0, r = n - 1; |
| while (l < r) { |
| int x = r - l, y = min(h[l], h[r]); |
| int s = x * y; |
| ans = max(ans, s); |
| if (h[l] <= h[r]) { |
| l++; |
| } else { |
| r--; |
| } |
| } |
| return ans; |
| } |
| }; |
| class Solution { |
| public: |
| int trap(vector<int>& h) { |
| int n = h.size(); |
| int pre = 0, suf = 0, ans = 0; |
| int l = 0, r = n - 1; |
| while (l < r) { |
| pre = max(pre, h[l]); |
| suf = max(suf, h[r]); |
| if (pre <= suf) { |
| ans += pre - h[l]; |
| l++; |
| } else { |
| ans += suf - h[r]; |
| r--; |
| } |
| } |
| return ans; |
| } |
| }; |
本文作者:pangyou3s
本文链接:https://www.cnblogs.com/pangyou3s/p/18288207
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步