15. 三数之和

三数之和

给你一个整数数组 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 。

https://leetcode.cn/problems/3sum/description/

解题思路

1 最简单三层for循环 三层遍历

2 第一层for循环,固定第一个值,后续使用双指针 减少循环次数

代码

cpp 复制代码
#include <iostream> 
#include <string> 
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;

// 固定一个节点 后续使用双指针
// 求三元组 使和为0 
vector<vector<int>> threeSum(vector<int>& nums) {
	int n = nums.size();
	// { { },{ },{ }  }
	vector<vector<int>> ans;
	// 从小到大排序
	sort(nums.begin(), nums.end());
	for (int i = 0; i < n; i++)
	{
		// 从第二个开始 ,如何和前一个相同 向后
		if (i > 0 && nums[i] == nums[i-1]) {
			continue;
		}
		// 取 相反值 b + c + target = 0 --> b + c = -target
		int target = -nums[i];
		// 双指针 应该放在 for 外面 如果放在里面 每次 j 都会从头开始
		int third = n - 1;
		for (int j = i + 1; j < n; j++)
		{
			if(j > i+1 && nums[j] == nums[j-1])
			{
				continue;
			}
			// 由于是从小到大 排序的 
			while (third > j && nums[j] + nums[third] > target) {
				third--;
			}
			if (third == j) {
				break;
			}
			// 如果相加为0 才添加到数组中
            if(nums[j] + nums[third] == target)
			{
				ans.push_back({ nums[i], nums[j], nums[third] });
			}
		}
		
	}
	return ans;
}

测试用例

cpp 复制代码
int main() {
    // 测试用例 1: 基础用例
    vector<int> nums1 = { -1, 0, 1, 2, -1, -4 };
    cout << "Test 1: [-1, 0, 1, 2, -1, -4]" << endl;
    auto res1 = threeSum(nums1);
    for (auto& v : res1) {
        cout << "  [" << v[0] << ", " << v[1] << ", " << v[2] << "]" << endl;
    }
    cout << "Expected: [-1, -1, 2] and [-1, 0, 1]" << endl << endl;

    // 测试用例 2: 全是0
    vector<int> nums2 = { 0, 0, 0, 0 };
    cout << "Test 2: [0, 0, 0, 0]" << endl;
    auto res2 = threeSum(nums2);
    for (auto& v : res2) {
        cout << "  [" << v[0] << ", " << v[1] << ", " << v[2] << "]" << endl;
    }
    cout << "Expected: [0, 0, 0]" << endl << endl;

    // 测试用例 3: 没有解
    vector<int> nums3 = { 1, 2, 3, 4 };
    cout << "Test 3: [1, 2, 3, 4]" << endl;
    auto res3 = threeSum(nums3);
    if (res3.empty()) {
        cout << "  No solution" << endl;
    }
    cout << "Expected: No solution" << endl << endl;

    // 测试用例 4: 多个重复解
    vector<int> nums4 = { -2, 0, 1, 1, 2 };
    cout << "Test 4: [-2, 0, 1, 1, 2]" << endl;
    auto res4 = threeSum(nums4);
    for (auto& v : res4) {
        cout << "  [" << v[0] << ", " << v[1] << ", " << v[2] << "]" << endl;
    }
    cout << "Expected: [-2, 0, 2] and [-2, 1, 1]" << endl << endl;

    // 测试用例 5: 空数组
    vector<int> nums5 = {};
    cout << "Test 5: []" << endl;
    auto res5 = threeSum(nums5);
    if (res5.empty()) {
        cout << "  No solution" << endl;
    }
    cout << "Expected: No solution" << endl << endl;

    // 测试用例 6: 元素少于3个
    vector<int> nums6 = { 0, 1 };
    cout << "Test 6: [0, 1]" << endl;
    auto res6 = threeSum(nums6);
    if (res6.empty()) {
        cout << "  No solution" << endl;
    }
    cout << "Expected: No solution" << endl << endl;

    // 测试用例 7: 大数测试
    vector<int> nums7 = { -1, 0, 1, 2, -1, -4, 2, 2, -3 };
    cout << "Test 7: [-1, 0, 1, 2, -1, -4, 2, 2, -3]" << endl;
    auto res7 = threeSum(nums7);
    for (auto& v : res7) {
        cout << "  [" << v[0] << ", " << v[1] << ", " << v[2] << "]" << endl;
    }
    cout << "Expected: [-4, 2, 2], [-3, 1, 2], [-1, -1, 2], [-1, 0, 1]" << endl << endl;

    // 测试用例 8: 排序后相邻相等的情况
    vector<int> nums8 = { -2, -2, -2, 1, 1, 1 };
    cout << "Test 8: [-2, -2, -2, 1, 1, 1]" << endl;
    auto res8 = threeSum(nums8);
    for (auto& v : res8) {
        cout << "  [" << v[0] << ", " << v[1] << ", " << v[2] << "]" << endl;
    }
    cout << "Expected: [-2, 1, 1]" << endl << endl;

    return 0;
}
相关推荐
浪客灿心27 分钟前
项目篇:模块设计与实现
数据库·c++
牛油果子哥q40 分钟前
【C++ STL vector】C++ STL vector 终极精讲:动态数组底层原理、两倍扩容机制、迭代器失效、增删查改、性能剖析与工程避坑指南
开发语言·c++
happymaker06261 小时前
LeetCodeHot100——42.接雨水
算法
阿正的梦工坊2 小时前
【Rust】07-错误处理:Option、Result 与 ? 运算符
开发语言·算法·rust
为何创造硅基生物3 小时前
独占指针的创建std::make_unique 本身自带堆出现
c++
kyle~3 小时前
ROS 2 与 Isaac Sim 联合仿真(一)体系架构、环境选型与基础通信闭环
c++·机器人·nvidia·仿真·ros2
努力努力再努力wz3 小时前
【内存管理与高并发内存池系列】从 mmap 到 malloc:文件映射、匿名映射与 glibc 内存分配机制详解
linux·c语言·数据结构·数据库·c++·qt·链表
八解毒剂3 小时前
数据结构-平衡二叉树——对二叉搜索树的优化
数据结构·c++·算法
运行时记录4 小时前
别再手动写提示词了 — SkillOpt 让技能文档自己进化
算法
起床困难户5754 小时前
条款20:协助完成返回值优化
c++