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;
}
相关推荐
45288655上山打老虎1 小时前
QFileDialog
c++
mit6.8242 小时前
dijk|tire+floyd+dp %
算法
独自破碎E2 小时前
【总和拆分 + 双变量遍历】LCR_012_寻找数组的中心下标
数据结构·算法
WBluuue2 小时前
Codeforces 1076 Div3(ABCDEFG)
c++·算法
u0109272712 小时前
模板编译期排序算法
开发语言·c++·算法
GIS瞧葩菜2 小时前
Cesium 轴拖拽 + 旋转圈拖拽 核心数学知识
人工智能·算法·机器学习
m0_686041612 小时前
C++中的适配器模式变体
开发语言·c++·算法
txzrxz2 小时前
结构体排序,双指针,单调栈
数据结构·算法·双指针算法·单调栈·结构体排序
AndrewHZ2 小时前
【AI黑话日日新】什么是AI智能体?
人工智能·算法·语言模型·大模型·llm·ai智能体
恒者走天下2 小时前
cpp c++辅导星球价格调整
c++