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;
}
Briefings in Bioinformatics投稿经验分享 阅读详情

相关推荐

基于人脸识别的课堂考勤系统 tkinter+openpyxl+face_recognition

基于face_recognition库实现人脸考勤系统功能。利用Python的tkinter模块来设计考勤系统的图形化界面,此外结合openpyxl模块,实现将学生的信息和考勤打卡数据保存到表格中,方便查看和调用。该系统具备“刷脸打卡”、“新学生注册”等功能。............

lyx4949的博客 6965

“3Sum”类问题介绍

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

liitdar的博客 1470

Java 开发 修改【冒险岛 079 私服】完整学习流程

第 1-2 天:环境搭建 + 运行原版 079 服务端,能正常登录游戏;第 3-4 天:纯配置文件修改,掌握倍率、属性、怪物、道具的修改,改出第一个「百倍经验私服」;第 5-10 天:Java 代码基础修改,掌握 Player/Skill/Monster 核心类的修改,实现技能无冷却、一刀秒怪、升级满属性;第 11-20 天:Java 代码进阶修改,掌握业务逻辑修改,实现死亡不掉经验、自动捡物、装备强化无失败;第 21-30 天。

萧曳丶 3894

leetcode:15. 三数之和

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

OceanStar的博客 2686

电池管理系统(BMS)系列(四)—数据采集之温度

属于BMS系列文章,介绍了电池包温度采集相关方式

zxx52113140的博客 5458

ROS2_IGH方案配置(二)——Ubuntu22.04 实时内核性能验证与调优

本文详细介绍了在Ubuntu22.04系统上配置ROS2_IGH方案时,如何验证和调优PREEMPT_RT实时内核性能。通过使用cyclictest工具进行基准测试和压力测试,分析中断与硬件延迟,并优化内核参数,确保系统满足工业控制领域对硬实时性的苛刻要求。文章还提供了针对ROS2的特殊优化建议和性能监控方案,帮助开发者实现毫秒级延迟的稳定控制。

weixin_30791095的博客 224

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

【机器人路径规划】基于改进型A*算法的机器人路径规划(Python代码实现)

本文针对传统A算法在机器人路径规划中存在的搜索效率低、路径不平滑等问题,提出了一种改进型A算法。该算法通过引入跳点搜索(JPS)技术优化子节点扩展方式,结合贝塞尔曲线或B样条曲线进行路径平滑处理,并采用动态启发式函数和自适应邻域搜索策略,显著提升了路径规划的效率和路径质量。实验结果表明,改进型A*算法在复杂环境下能有效减少搜索节点数量,缩短路径长度,提高路径平滑性,且具备动态避障能力。

2501_92867626的博客 1583

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

IntelliJ IDEA 中git使用说明书

IntelliJ IDEA 中git使用说明书

junyang2012的博客 5389

msf后渗透之获取登入password、远程控制、调用摄像头

在terminal输入load kili creds_all直接获取密码(不一定成功) 使用kiwi_cmd sekurlsa::logonpasswords获取密码

m0_61506558的博客 2964

LeetCode 15: 三数之和(3Sum)

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

printf___panda的博客 868

Cesium雷达追踪追踪(圆锥体效果)

【代码】Cesium雷达追踪追踪(圆锥体效果)

God's asylum的博客 2931

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

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

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

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

weixin_30702441的博客 340

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

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

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

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、付费专栏及课程。

余额充值