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;
}
相关推荐
水饺编程14 小时前
AT&T 汇编语言学习笔记开篇语
c语言·汇编·c++
Iruoyaoxh14 小时前
类和对象~
开发语言·c++
程序喵大人14 小时前
【C++进阶】STL算法与函数对象 - 04 find、count和any_of把查询写成意图
开发语言·c++·算法
豆沙沙包?14 小时前
c++中引用(P7-P11)
java·c++·算法
wuminyu14 小时前
虚拟线程底层ForkJoinPool的工作窃取算法机制
java·linux·c语言·jvm·c++
吹什么轩14 小时前
c++复习:c++11:lambda表达式
开发语言·c++
不会代码的小猴15 小时前
标准模板库(STL)
开发语言·c++·笔记·算法
ZhouDevin15 小时前
算法论文/高效微调4——DoRA:权重分解的低秩适配方法
算法
evans在进步15 小时前
LeetCode 200:岛屿数量——Java DFS 染色法详解
java·leetcode·深度优先
AI探索先锋15 小时前
A* 路径规划:四种算法的进化史-学习
学习·算法