LeetCode 15. 三数之和 3Sum(C语言)

LeetCode-15 三数之和 - 力扣 给你一个整数数组nums,判断是否存在三元组满足i!= ji!= k且j!= k,同时还满足。请你返回所有和为0且不重复的三元组。答案中不可以包含重复的三元组。不同的三元组是 [-1,0,1] 和 [-1,-1,2]。注意,输出的顺序和三元组的顺序并不重要。[]唯一可能的三元组和不为 0。[[0,0,0]]唯一可能的三元组和为 0。 阅读详情

题目描述:

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

题目解答:

方法1:排序法

在两数之和中,双指针求目标数的方法可以用在这里。外层遍历数组元素,将其相反数当作目标数,内层用双指针法确定是否存在目标数。需要注意的是重复元素的过滤,存储符合题意解之后,要跳过相等的数字,避免产生重复解。运行时间56ms左右,代码如下。

/**
 * Return an array of arrays of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
int comp(void* a, void* b) {
    return *(int*)a > *(int*)b ? 1 : -1;
}
int** threeSum(int* nums, int numsSize, int* returnSize) {
    int n = numsSize;
    qsort(nums, n, sizeof(int), comp);
    if(n < 3 || nums[0] > 0 || nums[0] + nums[1] + nums[2] > 0)
        return NULL;
    int** result = NULL;
    int i = 0, size = 0;
    int left = 0, right = 0;
    for(i = 0; i < n - 2 && nums[i] <= 0; i++) {
        left = i + 1;
        right = n - 1;
        while(left < right) {
            if(nums[i] + nums[left] + nums[right] > 0)
                right--;
            else if(nums[i] + nums[left] + nums[right] < 0)
                left++;
            else {
                size++;
                result = (int**)realloc(result, size * sizeof(int*));
                result[size - 1] = (int*)malloc(3 * sizeof(int));
                result[size - 1][0] = nums[i];
                result[size - 1][1] = nums[left];
                result[size - 1][2] = nums[right];
                while(left + 1 < n && nums[left] == nums[left + 1])
                    left++;
                while(right - 1 >= 0 && nums[right] == nums[right - 1])
                    right--;
                left++;
                right--;
            }
        }
        while(i + 1 < n && nums[i] == nums[i + 1])
            i++;
    }
    *returnSize = size;
    return result;
}
方法2: Hash+排序

排序完之后,将大于等于0的数字存入hash,直接申请最大正数max加1的空间,出现过的数字标记为真,否则标记为假。接下来利用两层循环,在循环最内侧,利用hash查找符合条件的第三个数字是否存在,在找第三个数字时,符合以下判断条件即可存储:

  1. target <= max && hash[target] && nums[j] < target (最后一个条件保证存储的结果都是递增的,避免重复结果)
  2. target == nums[j] && flag (flag表示nums[j]之前是否有与其相等的数字,有则为真,无则为假)

另外需要跳过第一层循环中重复元素。运行时间48ms,代码如下。

/**
 * Return an array of arrays of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
int comp(void* a, void* b) {
    return *(int*)a > *(int*)b ? 1 : -1;
}
int** threeSum(int* nums, int numsSize, int* returnSize) {
    int n = numsSize;
    int i = 0, j = 0, size = 0, t = 0;
    qsort(nums, n, sizeof(int), comp);
    if(n < 3 || nums[0] > 0 || nums[n - 1] < 0 || nums[0] + nums[1] + nums[2] > 0)
        return NULL;
    bool* hash = (bool*)calloc(nums[n - 1] + 1, sizeof(bool));
    for(i = 0; i < n; i++) { 
        if(nums[i] >= 0)
            hash[nums[i]] = true;
    }
    int** result = NULL;
    for(i = 0; i < n - 2 && nums[i] <= 0; i++) {
        for(j = i + 1; j < n - 1; j++) {
            bool flag = false;
            while(nums[j] == nums[j + 1]) {
                j++;
                flag = true;
            }  
            t = nums[i] + nums[j];
            if(t > 0)
                break;
            if((-t <= nums[n - 1] && hash[-t] && nums[j] < -t) || (-t == nums[j] && flag)) {
                size++;
                result = (int**)realloc(result, size * sizeof(int*));
                result[size - 1] = (int*)malloc(3 * sizeof(int));
                result[size - 1][0] = nums[i];
                result[size - 1][1] = nums[j];
                result[size - 1][2] = -t;
            }
        }
        while(nums[i] == nums[i + 1])
            i++;
    }
    *returnSize = size;
    return result;
}
Nordic开发者必备:SEGGER Embedded Studio免费许可证申请与配置全攻略 本文为Nordic芯片开发者提供了SEGGER Embedded Studio(SES)集成开发环境的详细配置指南。内容涵盖免费许可证的合规申请流程、项目创建、Nordic SDK集成,以及编辑器优化、构建调试配置、RTT日志输出等核心功能的高效设置,旨在帮助开发者构建深度优化的专业开发环境,显著提升嵌入式开发效率。 阅读详情

相关推荐

ESP8266 + MQTT :如何实现 LED 灯的远程控制

MQTT 是轻量级的、灵活的物联网消息交换和数据传递协议,致力于为 IoT 开发人员实现灵活性与硬件/网络资源的平衡。 NodeMCU 是一个开源的物联网平台。它使用 Lua 语言编程。该平台基于eLua开源项目,底层使用ESP8266 sdk 0.9.5版本。 在此项目中我们将实现 NodeMCU(ESP8266) 与 EMQ X Cloud 运营和维护的免费公共 MQTT 服务器远程控制 LED 灯,并使用 Arduino IDE 来对 NodeMCU ESP8266 进行编程。 EMQ X Cloud

emqx_broker的博客 3357

“3Sum”类问题介绍

3Sum”类问题,属于已排序的“Two Sum”类问题的升级版,都是给定一个已排序(升序或降序)的整型数组,然后在该数组中寻找若干个值,这些值的总和等于给定的target值。

liitdar的博客 1470

手把手教你用C语言给STM32写一个Modbus RTU从机库(含完整项目源码)

在工业自动化领域,Modbus RTU协议因其简单可靠的特点,成为RS485总线通信的事实标准。对于嵌入式开发者而言,为STM32等微控制器实现一个高效的Modbus RTU从机协议栈,是开发智能传感器、执行器等设备的必备技能。Modbus RTU从机的核心是一个状态机,需要处理帧接收、CRC校验、功能码解析和响应生成等环节。工业现场总会遇到意想不到的干扰情况,一个健壮的协议栈应该能够优雅地处理各种异常场景,而不是简单地崩溃或死锁。工业现场环境复杂,协议栈必须具备完善的异常处理机制。

weixin_30561425的博客 516

leetcode:15. 三数之和

题目来源 leetcode 题目描述 题目解析 题目分析 目的:要求从无序nums中找出3个数,正好和为0,要求求出所有的方案(不重复) 因为要求返回所有的方案,所以动态规划会比较麻烦,x掉。 暴力 从下面分析,可以知道,这是一个排列问题(跟顺序有关) 问题:我们需要从一个数组中选出三个数,有多少种组合?(每个nums[i]可以用无限次)(组合跟顺序没有关系) #include <iostream> #include <algorithm> #include <vec

OceanStar的博客 2686

1.Fay-UE5数字人工程导入(UE数字人系统教程)

ue5数字人系列教程(含源文件工程)

1万+

Vivado新手避坑指南:搞懂Generate Output Products和Create HDL Wrapper到底在干啥

本文深入解析Vivado设计流程中的Generate Output Products和Create HDL Wrapper两大关键步骤,帮助新手理解其核心功能与操作要点。通过详细讲解文件生成类型、关键选项设置及常见问题解决方案,指导开发者正确使用这两个功能,避免设计流程中的常见错误,提高FPGA开发效率。

weixin_29207149的博客 310

LeetCode—15.三数之和(3Sum)——分析及代码(C++)

LeetCode—15.三数之和[3Sum]——分析及代码[C++]一、题目二、分析及代码1. 双指针法(1)思路(2)代码(3)结果三、其他 一、题目 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。 注意:答案中不可以包含重复的三元组。 例如, 给定数组 nums = [-1, 0...

江南土豆的博客 481

编写一个程序实现顺序表的各种基本运算(假设顺序表的元数基本类型为Char)

/* *Copyright (c) 2016, 烟台大学计算机学院 *All rights reserved. *文件名称:main.cpp *作者:张旺华 *完成日期: 2016 年 7 月 1 日 *版本号:v1.0 *问题描述:编写一个程序实现顺序表的各种基本运算(假设顺序表的元数基本类型为Char) * */ #include #include #include

张旺华的博客 1万+

leetcode题解—3Sum

题目描述 给定有n个整数的数组nums,其中是否存在元素a,b,c使得a+b+c=0?在nums中找到所有满足条件的不重复的三元组a,b,c。 如输入 nums=[-1, 0, 1, 2, -1, -4],输出为 [ [-1, 0, 1], [-1, -1, 2]]。 解题思路 方法1:Brute Force 暴力法的解题思路很简单,用三个变量i,j,k分别遍历nums,将满足nums[i] + ...

相逢、陌路 243

创建 Qt Quick 项目

来看看如何使用 Qt Creator 创建 Qt Quick 项目!

青春不老,奋斗不止! 1万+

Google Earth Engine:计算逐年全球潜在蒸发量(PET)的 ERA 数据

通过获取温度、湿度和降水数据,并使用Penman-Monteith公式,我们可以得到每年的潜在蒸发量。在本文中,我们将使用Google Earth Engine平台和ERA(欧洲再分析气象数据集)数据来计算逐年全球的潜在蒸发量(PET)。接下来,我们需要对ERA数据进行预处理,以获取我们需要的潜在蒸发量数据。有了温度、湿度和降水数据,我们可以使用Penman-Monteith公式来计算每年的潜在蒸发量。最后,我们可以将计算得到的潜在蒸发量数据进行可视化,以便更好地理解全球的水汽蒸发情况。

VwajAlgorithm的博客 730

LeetCode 15: 三数之和(3Sum)

最直接的方法是使用三重循环,但时间复杂度为 O(n³),效率较低。通过排序和双指针技术,我们成功高效地解决了三数之和问题,找出了所有不重复的三元组。:首先对数组进行排序,这样相同的元素会相邻,便于去重。:对于所有指针,当遇到相同元素时,跳过以避免重复结果。根据三数之和与0的比较结果,决定如何移动指针。循环结束后跳过重复元素,避免产生重复结果。:遍历排序后的数组,固定第一个数。如果和小于0,左指针右移(增加和)如果和大于0,右指针左移(减小和)如果和为0,记录结果并移动双指针。:答案中不可包含重复的三元组。

printf___panda的博客 868

Autosar MCAL-S32K324 Fls配置-基于EB

Autosar MCAL Flash配置,基于S32K324,EB软件

赞的博客 1514

LeetCode:15. 3Sum 三数之和(C语言)

题目描述: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。 注意:答案中不可以包含重复的三元组。 示例: 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ] 来源:力扣(LeetCod...

C/C++攻城狮 1077

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

LeetCode 15. 3Sum 详解:排序+双指针与去重技巧

算法面试中,数组元素的组合求和是一类高频基础题,而双指针技术正是解决有序数组查找问题的核心手段。通过对原数组排序,可以将无序的穷举转化为可控的线性扫描,从而将暴力解法的 O(n³) 复杂度降至 O(n²)。在此基础上,如何正确处理重复三元组成为题目难点,外层跳过重复值、内层指针跳过连续相同元素,是保证结果不重不漏的关键。这类技巧不仅适用于 LeetCode 15 的 3Sum,还能推广到 4Sum 与 nSum 系列问题。从暴力解出发,逐步推导排序+双指针的设计思路,并给出 C++、Python、Java

weixin_30702441的博客 340

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Leetcode 15. 3Sum 三数之和

Leetcode 15. 3Sum 三数之和 标签(空格分隔): Leetcode 题目地址:https://leetcode-cn.com/problems/3sum/ 题目描述 给定一个包含 n 个整数的数组&nbsp;nums,判断&nbsp;nums&nbsp;中是否存在三个元素 a,b,c ,使得&nbsp;a + b + c = 0 ?找出所有满足条件且不重复的三元组。 注意:答案中...

CoderWangSon 196

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

LeetCode 15 — 3Sum(三数之和)

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Note: The solution set must not cont...

卓尔货币的博客 356

力扣(LeetCode)15. 三数之和(C++/C语言)

【墨染】不想暴力递归怎么办?用对撞指针干掉超时。

墨染 2473

【算法专题】双指针算法之15. 三数之和(力扣)

🏆本篇主题为:双指针算法之15. 三数之和(力扣)

cilmy23的note 2313

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

解题思路包括:1)排序预处理;2)固定一个元素后使用双指针寻找匹配的另外两个元素;3)去重处理避免结果重复。通过双指针优化,算法时间复杂度为O(n²),空间复杂度O(log n)。

专注 C++ 后端开发与 Linux 系统编程,深耕 STL 原理、多线程、内存管理、网络编程与服务端开发。用通俗语言拆解晦涩知识点,持续输出高质量学习笔记、踩坑复盘与面试干货。 980

LeetCode - 15 三数之和

因此当 nums[i] == nums[i-1] 时,我们就可以跳过 nums[i] 产生三元组的过程,因为必然和 nums[i-1] 产生的三元组发生重复。我们返回的结果是一个 int** 类型的,主要记录不重复的三元组,比如 [[-1,-1,2], [-1,0,1]],可以发现返回值本质是一个二维数组。比如对于返回值 [[-1,-1,2], [-1,0,1]] 来说,returnSize = 2,returnColumnSizes = [3, 3]输出:[[-1,-1,2],[-1,0,1]]

优快云 1493

力扣第15题:三数之和

学习目标: 力扣15. 三数之和 学习内容: 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。 注意:答案中不可以包含重复的三元组。 示例: 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ] 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/prob

童一的博客 334

15. 3 Sum (C,Python)

本文讲述了Array类中第15个问题的几种解法,实现语言包括C,Python, 难度为medium。 问题: Given an arraynumsofnintegers, are there elementsa,b,cinnumssuch thata+b+c= 0? Find all unique triplets in the array which give...

魔法师の屋子★↓☆ 3495

LeetCode之 15.三数之和 (3Sum)总结

生命不止,刷题不息~~~~~~ 前两天就一直在做15.三数之和,这个题在LeetCode和LeetCode中国上获赞很多,绝对的好题啊!不过,我喜欢这个题仅仅是因为它采用了快速排序的思想啦。 从捋清思路到代码实现,突破重重Bugs大关,终于提交成功,对于小白而言,实属不易,接下来就跟大家分享一下这个题的解题思路,并附上用C++,java,和python的代码实现,希望能给大家提供帮助! 1、...

相由心生的博客 386

LeetCode(C++)刷题计划:15-三数之和

15-三数之和 @Author:CSU张扬 @Email:csuzhangyang@gmail.com or csuzhangyang@qq.com Category Difficulty Pass rate algorithms Medium 24.31% Tags Companies array / two-pointers adobe / amazon...

神奇小海螺的博客 9150

LeetCode 力扣:15.3Sum + 16.3Sum Closest + 18.4Sum 排序 + 双指针遍历 题目+算法分析+Cpp解答

15.3Sum 排序 + 双指针遍历: ​ 首先,将给定的数组进行排序(从小到大的顺序)。 ​ 遍历排序后的数组中的每一个数,如果这个数之前已经讨论过了则可以跳过。 ​ 将取出的数作为“目标”,使用双指针在排序后的数组中找另外的两个数: ​ 一个左指针指向该取出的数的后一个数,即此时的最低位。 ​ 另一个右指针指向数组的最后一个数,即此时的最高位。 ​ 由于数组已经是从小到...

WULH 1177
上一篇: LeetCode 14. 最长公共前缀 Longest Common Prefix(C语言)
下一篇: LeetCode 16. 最接近的三数之和 3Sum Closest(C语言)
hang-7788
博客等级 码龄10年 47粉丝 71原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值