15. 三数之和

三数之和

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

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

示例 1:

输入:nums = [-1,0,1,2,-1,-4]

输出:[[-1,-1,2],[-1,0,1]]

解释:

nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。

nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。

nums[0] + nums[3] + nums[4] = (-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;
}
相关推荐
NAGNIP15 小时前
一文搞懂机器学习中的学习理论!
算法·面试
Evand J15 小时前
【MATLAB代码介绍】基于累积概率的三维轨迹匹配与定位,由轨迹匹配和卡尔曼滤波形成算法,带测试结果演示
算法·matlab·滤波·定位·导航·轨迹匹配
l1t15 小时前
NineData第三届数据库编程大赛:用一条 SQL 解数独问题我的参赛程序
数据库·人工智能·sql·算法·postgresql·oracle·数独
千金裘换酒15 小时前
LeetCode 链表两数相加
算法·leetcode·链表
NAGNIP15 小时前
一文搞懂机器学习中的优化方法!
算法
Sammyyyyy15 小时前
Rust 1.92.0 发布:Never Type 进一步稳定
java·算法·rust
alonewolf_9916 小时前
深入解析G1与ZGC垃圾收集器:原理、调优与选型指南
java·jvm·算法
小镇学者16 小时前
【c++】C++字符串删除末尾字符的三种实现方法
java·开发语言·c++
数据大魔方16 小时前
【期货量化实战】螺纹钢量化交易指南:品种特性与策略实战(TqSdk完整方案)
python·算法·github·程序员创富·期货程序化·期货量化·交易策略实战