力扣(LeetCode) ——15.三数之和(C++)

📌个人专栏: C++数据结构力扣------每日一题

题目:三数之和

给你一个整数数组 nums ,判断是否存在三元组 nums\[i, numsj, numsk] 满足 i != j、i != k 且 j != k ,同时还满足 numsi + numsj + numsk == 0 。请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例1:

输入: nums = -1,0,1,2,-1,-4
输出: \[-1,-1,2,-1,0,1]
解释: nums0 + nums1 + nums2 = (-1) + 0 + 1 = 0 。

nums1 + nums2 + nums4 = 0 + 1 + (-1) = 0 。

nums0 + nums3 + nums4 = (-1) + 2 + (-1) = 0 。

不同的三元组是 -1,0,1-1,-1,2

注意,输出的顺序和三元组的顺序并不重要。

示例2:

输入: nums = 0,1,1
输出: \[\]
解释: 唯一可能的三元组和不为 0 。

示例3:

输入: nums = 0,0,0
输出: \[0,0,0]
解释: 唯一可能的三元组和为 0 。

解题思路:

根据题目要求返回最终结果为0。

第一步排序处理

排序预处理便于后续通过双指针调整元素组合,缩小查找范围,跳过重复元素,避免结果中出现重复三元组。

第二步固定第一个元素再使用双指针找剩余两元素

遍历数组,以当前元素 numsi 作为三元组的第一个元素(固定值):

若 numsi > 0,由于数组已排序,后续元素均大于等于 numsi,三数之和必大于 0,可直接终止循环。

对于每个 numsi,使用双指针寻找另外两个元素:

left 指针从 i+1 开始,向右移动;

right 指针从数组末尾开始,向左移动。
第三步双指针调整与求和判断

计算当前三数之和 sum = numsi + numsleft + numsright

若 sum > 0:说明和过大,需减小右侧元素,将 right 左移;

若 sum < 0:说明和过小,需增大左侧元素,将 left 右移;

若 sum == 0:找到符合条件的三元组,存入结果集。

之后同时移动 left 右移和 right 左移,继续寻找新的组合;

移动过程中跳过重复元素(如 numsleft 与前一个元素相同则继续右移,numsright 与后一个元素相同则继续左移),避免重复三元组。
第四步跳过重复的固定元素

遍历完一个 numsi 后,将 i 右移,并跳过所有与 numsi-1 相同的元素,确保第一个元素不重复,进一步避免结果重复。

通过以上步骤,算法在排序O(n log n)的基础上,通过双指针遍历O(n²),高效找到所有不重复的三元组,时间复杂度为O(n^2^),空间复杂度主要为排序所需的O(log n)

最终代码:

cpp 复制代码
vector<vector<int>> threeSum(vector<int>& nums) 
{
	vector<vector<int>> ret;
	//排序
	sort(nums.begin(), nums.end());
	int n = nums.size();
	int i = 0;
	while(i < n)
	{
	    if(nums[i] > 0) break;
	    int left = i + 1, right = n - 1;
	    while(left < right)
	    {
	        int sum = nums[left] + nums[right];
	        if(sum + nums[i] > 0) right--;
	        else if(sum + nums[i] < 0) left++;
	        //判断是否等于0
	        else
	        {
	            //存放值
	            ret.push_back({nums[i],nums[left],nums[right]});
	            left++;
	            right--;
	            //跳过重复元素
	            while(left < right && nums[left] == nums[left - 1]) left++;
	            while(left < right && nums[right] == nums[right + 1]) right--;
	        }
	    }
	    i++;
	    //跳过重复元素
	    while(i < n && nums[i] == nums[i-1]) i++;
	}
	return ret;
	}

赶紧动起手来吧!!!

点击下方即可跳转
三数之和

相关推荐
搬砖魁首1 天前
基础能力系列 - 多线程2 - 条件变量
c++·rust·条件变量·原子类型·线程同步互斥
youngerwang1 天前
【从搬运工到协处理器:网卡芯片架构、算法、验证与边缘演进深度剖析】
网络·算法·架构·芯片
chase_my_dream1 天前
C++ + SLAM 高频面试问题整理
开发语言·c++·面试
牛油果子哥q1 天前
【C++ STL string 】C++ STL string 终极精讲:底层原理、内存机制、全套API、深浅拷贝、易错坑点与工程实战规范
数据库·c++
KaMeidebaby1 天前
卡梅德生物技术快报|纯化重组蛋白实操详解
人工智能·python·tcp/ip·算法·机器学习
手写码匠1 天前
从零实现 Prompt 工程引擎:结构化提示、自动优化与多轮自省体系
人工智能·深度学习·算法·aigc
无限码力1 天前
阿里算法岗 0530笔试真题 - 多约束条件下的元素匹配统计
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试
lqqjuly1 天前
MLA — 多头潜在注意力深度解析
深度学习·神经网络·算法
吴可可1231 天前
SolidWorks草图转三维DWG技巧
算法
凡人叶枫1 天前
Effective C++ 条款04:确定对象被使用前已先被初始化
java·linux·开发语言·c++·嵌入式开发