
LeetCode.两数之和&三数之和&最接近的三数之和&四数之和
为什么不能直接用双指针? 哈希表方法的时间复杂度是怎样的? 哈希表与双指针方法的时间复杂度对比? 双指针的时间复杂度如何? 如何处理重复的答案? 剪枝的技巧是否会导致超时? 基本思路: 排序数组后,使用双指针法从数组两端开始,寻找满足和的三元组。 关键优化: 由于排序后的数组去重,剪枝方法需要考虑如何高效地排除重复的解。直观的方法是记录已经得到的三元组,避免重复计数,但这种方法的时间复杂度可能较高。 正确剪枝方式: 在排序数组中,固定左指针,右指针从右边开始遍历,利用数组的有序性去重。 使用双指针法排序数组。 计算当前和与目标值的差,记录绝对值最小的解。 在双指针移动过程中,根据和与目标的关系决定指针移动方向。 排序数组,使用双指针法思想扩展到四数之和。 在固定前两个数的基础上,寻找剩下的两个数的和。 减少重复计算,避免处理冗余情况。
发布日期:2025-04-05 03:07:18
浏览次数:11
分类:精选文章
本文共 4519 字,大约阅读时间需要 15 分钟。
解题思路与实现总结
LeetCode1. 两数之和
问题描述: 找出两数之和等于目标值的下标对。
用户提到的核心问题:解决方案分析:
- 暴力模拟法: 简单暴力解法,适用于小规模数据,但效率较低。
- 哈希表优化法: 使用哈希表(字典)存储元素及其索引。遍历数组时,快速查找目标值与当前元素之和的补丁是否存在,如果存在返回对应的索引对。这种方法的时间复杂度为 O(N log N),因为每个元素的插入、查询操作都需要 O(log N) 时间。
优化点:
- 使用哈希表避免了嵌套循环的时间复杂度问题。
- map 的 key 是数组中的值,value 是对应的索引。遍历数组时,判断是否存在目标值与当前值之和的补丁。
实现代码:
#include#include using namespace std;class Solution {public: vector twoSum(vector nums, int target) { unordered_map m; vector ans; for (int i = 0; i < nums.size(); ++i) { if (m.count(target - nums[i])) { ans.push_back(m[target - nums[i]]); ans.push_back(i); break; } m[nums[i]] = i; } return ans; }};
LeetCode3. 三数之和
问题描述: 找出三数之和等于目标值的三元组。
用户提到的核心问题:解决方案分析:
优化点:
- 排序数组后,双指针法的时间复杂度为 O(N log N)。
- 去除重复解的方法是记录已经加入结果中的三元组,避免重复计数。
实现代码(排序后双指针法):
#include#include using namespace std;class Solution {public: vector > threeSum(vector nums) { vector > ans; if (nums.size() < 3) return ans; sort(nums.begin(), nums.end()); for (int i = 0; i < nums.size(); ++i) { if (nums[i] > 0) continue; //剪枝条件 int left = i + 1; int right = nums.size() - 1; while (left < right) { long long sum = (long long)nums[i] + nums[left] + nums[right]; if (sum == 0) { ans.push_back({nums[i], nums[left], nums[right]}); //去重处理:如果当前三个元素与前一个相同,则跳过 while (left < right && nums[left] == nums[left - 1]) ++left; while (left < right && nums[right] == nums[right - 1]) --right; } else if (sum < 0) { ++left; } else { --right; } } } return ans; }};
LeetCode16. 最接近的三数之和
问题描述: 找出最接近目标值的三个数之和。
解决方案分析:优化点:
- 減少比较操作通过绝对值判断优化性能。
- 排序后保证有序性,避免重复计算。
实现代码:
#include#include using namespace std;class Solution {public: int threeSumClosest(vector nums, int target) { sort(nums.begin(), nums.end()); int closeNum = nums[0] + nums[1] + nums[2]; int bestDiff = INT_MAX; for (int i = 0; i < nums.size(); ++i) { int left = i + 1; int right = nums.size() - 1; while (left < right) { long long sum = nums[i] + nums[left] + nums[right]; int diff = abs((int)(sum) - target); if (diff < bestDiff) { bestDiff = diff; closeNum = sum; } if (sum < target) { ++left; } else if (sum > target) { --right; } else { break; } } } return (int)closeNum; }};
LeetCode18. 四数之和
问题描述: 找出四个数之和等于目标值的四元组。
解决方案分析:优化点:
- 初始排除三个及以上相同元素的 fused纸条元组。
- 在四数之和的情况下,需要双层循环来处理溶液选择,优化搜索空间。
实现代码:
#include#include using namespace std;class Solution {public: vector fourSum(vector nums, int target) { sort(nums.begin(), nums.end()); vector result; int size = nums.size(); for (int a = 0; a < size; ++a) { if (a > 0 && nums[a] == nums[a - 1]) continue; //去重 for (int b = a + 1; b < size; ++b) { if (b > a + 1 && nums[b] == nums[b - 1]) continue; //去重 int i = b + 1; int j = size - 1; while (i < j) { long long sum = nums[a] + nums[b] + nums[i] + nums[j]; if (sum < target) { ++i; //为了得到更小的和,尝试更大的数 } else if (sum > target) { --j; //为了得到更小的和,尝试更小的数 } else { result.push_back({nums[a], nums[b], nums[i], nums[j]}); //去重处理:判断是否有重复的解 while (i < j && nums[i] == nums[i - 1]) ++i; while (i < j && nums[j] == nums[j - 1]) --j; } } } } return result; }};
总结
以上内容包括了多个经典算法问题的解法和优化思路,涵盖了双指针法、哈希表优化、剪枝技巧等内容。这些方法通过排序和双指针缩小搜索空间,保证了算法在较大数据集上的性能。每个问题都有具体的解决方案和优化解释,适合参考和实践。
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年04月18日 08时42分21秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
响应的HTTP协议格式+常见的响应码
2021-05-18
springboot redis key乱码
2021-05-19
解决打开 json 文件中文乱码的问题
2025-03-28
计算机网络基础:PKI(公钥基础设施)
2025-03-28
乒乓球问题
2025-03-28
回溯法介绍
2025-03-28
有了Trae,人人都是程序员的时代来了
2025-03-28
CentOS 系列:CentOS 7文件系统的组成
2025-03-28
Docker部署postgresql-11以及主从配置
2025-03-28
EnvironmentNotWritableError: The current user does not have write permissions to the target environm
2025-03-28
kali安装docker(亲测有效)
2025-03-28
PHP系列:PHP 基础编程 2(时间函数、数组---实现登录&注册&修改)
2025-03-28
PHP系列:使用PHP实现登录注册功能的完整指南
2025-03-28
"WARNING: Increasing RAM size to 1GB" and "Cannot set up guest memory 'xxx.ram': Invalid argument".
2025-03-28
04-docker-commit构建自定义镜像
2025-03-28
05-docker系列-使用dockerfile构建镜像
2025-03-28
09-docker系列-docker网络你了解多少(下)
2025-03-28
#C8# UVM中的factory机制 #S8.2.3# 重载sequence哪些情形
2025-03-29
cytoscape安装java_Cytoscape史上最全攻略
2025-03-29