3Sums——Leetcode 0015三数之和_枚举类方法

算法基础之数组双指针(Leetcode题型归纳) 数组双指针(Leetcode题型归纳)1.前言2.双指针基础3.相向双指针3.1定义3.2真题分析3.2.1两数之和(1)3.2.2两数之和-输入有序数组(167)3.2.3三数之和(15)3.2.4最接近的三数之和(16)3.2.5四数之和(18)3.2.6盛最多水的容器(11)3.2.7有效三角形的个数(611)4.同向双指针-快慢指针4.1定义4.2真题分析4.1.1删除排序数组中的重复项(26)4.1.2移除元素(27)4.1.3删除排序数组中的重复项(80)4.1.4移动零(283)4.1.5数组 阅读详情

题目描述

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i!=ji != ji!=j, i!=ki != ki!=k, and j!=kj != kj!=k, and nums[i]+nums[j]+nums[k]==0nums[i] + nums[j] + nums[k] == 0nums[i]+nums[j]+nums[k]==0.

Notice that the solution set must not contain duplicate triplets.

Example 1:

Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]

Example 2:

Input: nums = []
Output: []

Constraints:

0<=nums.length<=30000 <= nums.length <= 30000<=nums.length<=3000
−105<=nums[i]<=105-10^5 <= nums[i] <= 10^5−105<=nums[i]<=105

解题思路

直接基于三层循环的思路

无论是算法新手还是老司机,这个方法应该都是极易想到并且理解的。设定三层循环,找到其所有的元素个数为3的子集并完成子集合并即可实现,找到其中和为0的子集即为最后结果。

def threeSum_General(self, nums: List[int]) -> List[List[int]]:
    # 元素数目小于3个,不存在解
    if len(nums) < 3:
        return []
    # 元素个数刚好为3个,如果恰好为0,则为
    if len(nums) == 3:
        if sum(nums) == 0:
            return [nums]
        else:
            return []
    # 元素个数>3个
    result = []
    # 3层循环
    for i in range(0, len(nums)):
        for j in range(i + 1, len(nums)):
            for k in range(j + 1, len(nums)):
                # 判断是否和为零
                if nums[i] + nums[j] + nums[k] == 0:
                    # 满足条件的话对三个元素进行排序,并检查在结果集合中是否已经存在该结果
                    temp = sorted([nums[i], nums[j], nums[k]])
                    # 如果还不存在该解,将其加入最终的解集
                    if temp not in result:
                        result.append(list(temp))
    return result

但是在使用上述方法时,leetcode直接就报了超时的错误。不难理解,即便数组长度范围限制在3000以内,这种O(N3)O(N^3)O(N3)的解法的耗时也是极其可观的。为此,只能另寻别路。

先排序,再循环的解决方法

之所以考虑先排序,是因为在上述的做法中我们每一步都要做一次排序的工作,因此不如直接对整个数组做排序,随后采用三层循环的方案。这样子可以直接保证三个数字的顺序,代码如下:

def threeSum_Sort(self, nums: List[int]) -> List[List[int]]:
    # 元素数目小于3个,不存在解
    if len(nums) < 3:
        return []
    # 元素个数刚好为3个,如果恰好为0,则为
    if len(nums) == 3:
        if sum(nums) == 0:
            return [nums]
        else:
            return []
    # 元素个数>3个
    result = []
    # 3层循环
    nums = list(sorted(nums))
    for i in range(0, len(nums)):
        if i == 0 or nums[i] != nums[i - 1]:
            for j in range(i + 1, len(nums)):
                if j == i + 1 or nums[j] != nums[j - 1]:
                    for k in range(j + 1, len(nums)):
                        if k == j + 1 or nums[k] != nums[k - 1]:
                            # 判断是否和为零
                            if nums[i] + nums[j] + nums[k] == 0:
                                # 满足条件的话对三个元素进行排序,并检查在结果集合中是否已经存在该结果
                                temp = [nums[i], nums[j], nums[k]]
                                result.append(list(temp))
    return result

通过分析上述代码不难发现,这种先排序的方法并不会影响时间复杂度,因为三层循环的框架依旧在。那么如何才能摆脱三层循环的限制呢?官方的题解在分析时指出,在排序之后的数组numsnumsnums中枚举时,由于取到的三个数字在顺序上是升序的,在选定a,ba, ba,b之后,有唯一的ccc满足a+b+c=0a+b+c=0a+b+c=0这一条件,那么下一次枚举时,对应找到b′,c′b', c'b′,c′,满足上述条件,由于此时b′>bb'>bb′>b,那么此时c′<cc'<cc′<c,因此内层的两个循环其实可以合并为一个,这正是我们在对数组进行排序后带来的新特性。这样一来,第一层枚举在最外层,内层的两层枚举变为了同一层,时间复杂度自然从O(N3)O(N^3)O(N3)变为O(N2)O(N^2)O(N2),而排序带来的复杂度为O(NLogN)O(NLogN)O(NLogN),在取渐进意义时其可以忽略,整体的时间复杂度记为O(N2)O(N^2)O(N2)。下面给出代码:

'''
既然上述方案会导致超时,只能另寻方法
基于双指针的方法,主要改进的思路在于,既然三层循环会带来O(N^3)的复杂度,那么必须想办法摒弃。
由于我们需要考虑最终集合中元素不会重复,一种简单的做法就是先对整个数组排序
在枚举过程中,如果前两个数字a, b一旦确定,那么就有唯一的c与之匹配使得a+b+c=0
而当b向右移动枚举到b'时,由于b'>b,那么满足条件的c'<c也是必然的
因此b和c的枚举可以放到同一层循环,b由小到大,c由大到小
'''
def threeSum(self, nums: List[int]) -> List[List[int]]:
    if len(nums) < 3:
        return []
    if len(nums) == 3:
        if sum(nums) == 0:
            return [nums]
        else:
            return []
    result = []
    # first sort the given array with time complexity O(NlogN)
    nums = list(sorted(nums))
    for i in range(0, len(nums)):
        # nums[i] != nums[i - 1]这一条件是为了排除连续两个相同的数字会被单一枚举对象连续用两次,从而导致重复
        # 下面的所有该判断都是同一目的
        if i == 0 or nums[i] != nums[i - 1]:
            # 第三层枚举所用指针初始化,从后往前
            k = len(nums) - 1
            # 第二层枚举
            for j in range(i + 1, len(nums)):
                # 此处判断与上一个判断目的相同
                if j == i + 1 or nums[j] != nums[j - 1]:
                    # 双指针在使用时需要判断两个指针的相对位置,右指针不能越过左指针
                    # 在指针j更新后,满足条件的k对应的索引势必比上次要小
                    while nums[i] + nums[j] + nums[k] > 0 and k > j:
                        k -= 1
                    # 如果k == j,此时会导致三个数中出现重复,不满足集合的特性,不能作为结果
                    if nums[i] + nums[j] + nums[k] == 0 and k != j:
                        result.append([nums[i], nums[j], nums[k]])
    return result

以上是三数之和问题使用枚举方法求解的基本步骤,大家有新的方法的话可以在评论区交流(上述内容主要来自Leetcode官解,这里只是为了自己记录一下刷题过程中的心得~)

Synares病毒实战:如何从U盘感染中恢复你的Excel和EXE文件(附专杀工具推荐) 本文详细介绍了Synares感染型病毒的典型特征与传播机制,特别是其通过U盘感染Excel和EXE文件的行为。文章提供了一套从应急隔离、诊断到使用专杀工具进行深度清除与文件恢复的完整实战流程,并推荐了有效的安全软件和修复方法,旨在帮助用户最大程度救回重要数据并构建长效安全防护习惯。 阅读详情

相关推荐

记录rk3588 在Linux 6.1内核版本声卡 bug。

rk3588 Audio bug

Yongheng6的博客 855

【数据结构基础_数组】Leetcode 15.三数之和

双指针

cwtnice的博客 238

RT-Thread与ROS2通信:micro-ROS在STM32上的移植实践

本文详细介绍了在STM32平台上使用RT-Thread实时操作系统移植micro-ROS实现与ROS2通信的实践方案。通过对比rosserial方案,重点阐述了micro-ROS基于XRCE-DDS协议栈在数据可靠性(丢包率低于1%)、双模式通信(UDP/串口)以及C/C++混合编程方面的优势,为嵌入式设备与ROS2的高效通信提供了完整解决方案。

emacs5lisp的博客 328

力扣-15三数之和3Sums

题目 例子 思路 代码

qq_37299596的博客 282

新手如何结合pbootCMS和宝塔面板快速构建网站

摘要: 新手可通过pbootCMS(轻量CMS)和宝塔面板(可视化工具)快速搭建网站,无需命令行。步骤包括:1) 准备服务器(Linux/CentOS7.x)和域名;2) 安装宝塔面板并配置LNMP环境(PHP7.4+MySQL5.7);3) 创建网站目录,上传并解压pbootCMS源码,设置文件权限;4) 运行安装向导,填写数据库信息和管理员账号;5) 测试前台/后台功能,优化性能并绑定域名。全程约30-60分钟,宝塔简化运维,pbootCMS便于内容管理,适合零基础用户。注意定期更新和备份以保障安全。

qinzhenyan的博客 1642

Springboot(五十六)SpringBoot3集成SkyWalking

Dskywalking.collector.backend_service:表示skywalking的collector服务的IP及端口。注意上图中红框标注的位置,我们可以根据启动Springboot项目启动时候控制台输出的ID进行筛选。注意上图中红框标注的位置,我们可以根据启动Springboot项目启动时候控制台输出的ID进行筛选。其他的版本的 APM 地址(这个我不需要,我们是在docker中部署的,留给有需要的同学)其他的java 版本的 Agents 地址。

camellia的博客 2601

算法:3个数之和15. 3Sum

15. 3Sum Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. Notice that the solution set must not contain duplicate triplets. Example 1: Input: nums =

AI架构师易筋 333

推荐系统[九]项目技术细节讲解z2:搜索Query理解[Term Weight、Query 改写、同义词扩写]和语义召回技术

在 pooling 方法上,我们也尝试过不同层 pooling,或者在多层上增加 attention 聚合 BERT 多层结果,效果和最后一层所有 token 做 average pooling 相当。损失函数方面,在排序阶段使用pairwise比 pointwise 损失函数的效果会更好。

丨汀、的博客 1109

15. 3Sum

刷题笔记 15. 3Sum 题目 Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. Notice that the solution set must not contain duplicate triplets. 思路 又是一道没自己做出来的

weixin_43914325的博客 267

微信小程序 - 实现嵌套H5页面唤起微信支付的实现方案+完整流程源码,微信小程序webview(H5页面)调用微信小程序支付,嵌套h5页面怎么实现小程序支付(Vue2/3移动端H5网页、公众号网页等)

h5嵌入微信小程序微信支付,H5网页嵌入到微信小程序内如何支付,微信小程序webview组件交互,内联h5页面并网页实现微信支付,微信H5页面实现微信小程序支付,微信小程序嵌套webview实现小程序微信支付,小程序中内嵌H5网页支付怎么办,用网页的支付还是小程序的支付?支付没反应,支付报错怎么办,微信小程序内嵌h5,h5调用小程序支付功能解决方案,H5网页cors跨域,真机测试无法唤起支付,无法唤起支付,uniapp微信小程序,h5小程序调用微信支付,微信小程序内嵌H5页面,如何实现微信支付功能,微信小程

🏆 前端领域优质创作者 1万+

如何实现在Go语言中替换程序自身

总结起来,我们可以通过将新的程序二进制文件写入磁盘,并在运行时启动这个新的程序来实现在Go语言中替换程序自身。在Go语言中,有时候我们需要在程序运行时替换程序自身,例如更新程序版本或者进行热重启。本文将介绍一种正确的方式来实现在Go语言中替换程序自身的方法,并提供相应的源代码示例。此外,替换程序自身可能会导致正在运行的程序产生意外行为或终止,请谨慎使用,并确保在合适的时机进行替换操作。实现替换程序自身的关键是将新的程序二进制文件写入到磁盘,并在运行时启动这个新的程序。函数启动新的可执行文件,并在后台运行。

HoUnix的博客 289

【LeetCode 面试经典150题】15. 3Sum 三数之和

ji!= k, andj!= k, and。

qq_43513394的博客 596

分享一份小度在家1C系列NV2101刷机保姆级教程,轻松解锁第三方应用!(内含详细教程、刷机工具和救砖等工具)

分享一份小度在家1C系列NV2101刷机保姆级教程,轻松解锁第三方应用!(内含详细教程、刷机工具和救砖等工具)

XiaoqiangClub的博客 7169

leetcode15三数之和

参考文章 代码:自己代码 参考代码: class Solution { public List<List<Integer>> threeSum(int[] nums) {// 总时间复杂度:O(n^2) List<List<Integer>> ans = new ArrayList<>(); if (nums == null || nums.length <= 2) return ans;

Mr.田的博客 359

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

3Sums

15. 3Sums 题目链接 题意 解法 代码 算法复杂度 要点 题目链接:15. 3Sums 题意 给出一个数组,求出该数组中所有和为给定值的三元组的集合 解法 在有序数组中可以从用两个端点开始的两个下标来逐步逼近目标和,因此可以先将给定数组排序,然后每次固定一个数,在剩下的区间用左右两个下标来逼近给定和。 代

helowow的博客 551

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

LeetCode之16----3Sums Closest

题目: Given an arraySofnintegers, find three integers inSsuch that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input ...

defs6497的博客 194

Devexpress16.2.6破解工具

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

【LeetCode】3Sum 解题报告

这道题凭我现有知识实在解答不上来,只好网上搜索解法,才发现 K Sum 是一类问题,但是网上没有比较简洁的代码,我想对于初学者来说,可能还是想先看看这道题怎么解,然后才有兴趣去看其扩展吧。 【题目】 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Fin

跳出温水的青蛙 3万+

【每日一算法】20180403- 3Sums

Given an array S of n integers, are there elements a, b, c in S 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 contain dupli...

90ed9e4f的博客 438

2Sums&3Sums

从来没刷算法题,但是突然感觉这样还是不完整,听从学长建议从leetcode下手,感受了一下2Sums和3Sums,觉得自己算法真是差太多了。。。 从2Sums说起 起手双循环,不出意料超时了,于是开始想可以优化的地方,当时想着要是能把所有的遍历过的值的信息储存起来,就可以遍历一遍了,但是我大概觉得这样换个vector储存好像没用,要找匹配的还是要再遍历。于是就没想法了。上网找答案,第一下找

u012876995的博客 664

【leetcode】3sums

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Note: Elements in a triplet (a,b,c

唐辰砂的博客 990

3 sums题解

题干: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.Note: Elements in a triplet (a,b,c) must

zslomo的博客 545

【LeetCode】详解三数之和15. 3Sum Given an array nums of n integers, are there elements a, b, c in nums

文章目录前言正文原题:思路1:思路2:思路3:总结 前言 有一段时间没刷LeetCode了,发现有点生疏,临近大三,需要多刷题!通过这篇博客记录LeetCode15题三数之和的思路。 正文 原题: 链接:三数之和 Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c ...

Qonent的博客 1773

leetcode 303: Range Sum Query - Immutable

Range Sum Query - Immutable Total Accepted: 696 Total Submissions: 2406 Difficulty: Easy Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), i

西施豆腐渣 5684

小白算法打卡第一天!!!LeetCode第一题:2sum & 3Sum

作者:wu_yan_zu 链接:https文章目录3sum题目:解法:排序 + 双指针算法流程Python3C++JAVA 3sum题目: Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. Notice that the solution set

燃烧吧秀发 367

Leetcode 题解 - 动态规划-数组区间(8):数组区间和

[LeetCode] Range Sum Query - Immutable 区域和检索 - 不可变 Given an integer arraynums, find the sum of the elements between indicesiandj(i≤j), inclusive. Example: Given nums = [-2, 0, 3, -5, 2, -...

qq_40320556的博客 851

LeetCode#15. 3Sum

15. 3Sum Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. Notice that the solution set must not contain duplicate triplets. Example 1: Input: nums =

ashtime 141
上一篇: Knight On the Chessboard
下一篇: TrailingZeros——Leetcode 0172 寻找尾零的数目
CAAT9
博客等级 码龄10年 21粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值