LeetCode第十五题:三数之和【15/1000 python】

👤作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。
会一些的技术:数据分析、算法、SQL、大数据相关、python
作者专栏每日更新:
LeetCode解锁1000题: 打怪升级之旅

LeetCode解锁1000题: 打怪升级之旅https://blog.csdn.net/cciehl/category_12625714.html
python数据分析可视化:企业实战案例https://blog.csdn.net/cciehl/category_12615648.html
备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

在算法和数据结构的学习中,"三数之和"问题是一个非常经典的问题,它不仅考验着程序员的基础算法能力,还涉及到如何有效地利用数据结构来解决实际问题。接下来,我们将通过一个由浅入深的方式,详细解析这个问题,并给出相应的案例和代码实现。

问题描述

在"三数之和"问题中,给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c,使得 a + b + c = 0?找出所有满足条件且不重复的三元组。

 

简单解法 — 暴力法(不推荐)

一种最直观的方法是使用三重循环遍历所有可能的三元组组合,检查它们的和是否为 0。虽然这种方法简单直观,但其时间复杂度为 O(n^3),在数据量较大时会导致严重的性能问题。

代码实现

def three_sum_brute_force(nums):n = len(nums)result = []for i in range(n):for j in range(i+1, n):for k in range(j+1, n):if nums[i] + nums[j] + nums[k] == 0:triplet = sorted([nums[i], nums[j], nums[k]])if triplet not in result:result.append(triplet)return result

高效解法 — 双指针法

为了优化算法,我们可以采用双指针法。首先对数组进行排序,然后使用一个固定指针遍历数组,对于每个固定指针的位置,使用两个指针(一个在固定指针之后,一个在数组末尾),通过移动这两个指针来搜索和为0的三元组。

解题步骤

  1. 排序:对数组进行排序。
  2. 遍历:固定一个数 nums[i],然后使用左右指针指向 nums[i] 后面的两端,数字分别为 nums[L] 和 nums[R],计算三个数的和 sum 判断是否满足条件。
  3. 去重:跳过重复的数字。

代码实现

def three_sum(nums):nums.sort()n, result = len(nums), []for i in range(n):if i > 0 and nums[i] == nums[i-1]:continueL, R = i+1, n-1while L < R:total = nums[i] + nums[L] + nums[R]if total < 0:L += 1elif total > 0:R -= 1else:result.append([nums[i], nums[L], nums[R]])while L < R and nums[L] == nums[L+1]:L += 1while L < R and nums[R] == nums[R-1]:R -= 1L += 1R -= 1return result

案例分析

假设输入数组为 nums = [-1, 0, 1, 2, -1, -4]

  1. 排序后的数组为 [-4, -1, -1, 0, 1, 2]
  2. 固定第一个数为 -4,在 -12 的范围内寻找两数之和为 4 的组合,不存在,移动固定数。
  3. 固定第二个数为第一个 -1,找到了两数之和为 1 的组合,即 [-1, 0, 1]
  4. 继续遍历,找到第二个组合为 [-1, -1, 2]

双指针法图解

给定一个数组nums = [-4, -1, -1, 0, 1, 2],目标是找出所有唯一的三元组,它们的和为0。

1. 排序

首先,对数组进行排序。

排序后的数组: [-4, -1, -1, 0, 1, 2]

2. 遍历和双指针搜索

对数组进行遍历,每次遍历中,固定一个元素,然后用两个指针在固定元素之后的数组部分进行搜索,一个指针从左向右移动(左指针),另一个从右向左移动(右指针)。

第一轮遍历

  • 固定元素: -4 (索引0)
  • 左指针: 在-1 (索引1)
  • 右指针: 在2 (索引5)
数组: [-4, -1, -1, 0, 1, 2]
固定元素: -4 (索引0)
左指针:    ↑ (索引1)
右指针:                  ↑ (索引5)

检查和调整

  • 第一次和为-4 + (-1) + 2 = -3 < 0,左指针向右移动。
  • 左指针移动到第二个-1处,和为-4 + (-1) + 2 = -3 < 0,左指针继续向右移动。
  • 左指针移动到0处,和为-4 + 0 + 2 = -2 < 0,左指针继续向右移动,直到左指针与右指针相遇,这轮遍历结束。

在这轮遍历中,没有找到和为0的三元组。

第二轮遍历

  • 固定元素变为: -1 (索引1)
  • 左指针: 在-1 (索引2)
  • 右指针: 在2 (索引5)
数组: [-4, -1, -1, 0, 1, 2]
固定元素: -1 (索引1)
左指针:        ↑ (索引2)
右指针:                  ↑ (索引5)

遍历的过程重复上述步骤,对每个固定元素,移动左右指针,并根据三数之和是大于还是小于0来调整指针的位置。

 

关键点

  • 当和小于0时,只移动左指针向右。
  • 当和大于0时,只移动右指针向左。
  • 当找到和为0的三元组时,记录下来,并同时移动左指针和右指针,寻找新的可能组合。

3. 去重

为了避免记录重复的三元组,每次在移动指针时,需要跳过重复的值。

结论

通过以上的解析和示例代码,我们可以看出,相比于暴力法,双指针法大大提高了"三数之和"问题的求解效率。

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/600733.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【安全工具】信息收集——ENScan_GO

1.初次使用 运行命令生成配置文件 ./enscan -v 2.配置cookie 参考介绍 wgpsec/ENScan_GO: 一款基于各大企业信息API的工具&#xff0c;解决在遇到的各种针对国内企业信息收集难题。一键收集控股公司ICP备案、APP、小程序、微信公众号等信息聚合导出。 (github.com) 3.友情提…

SAP ERP 公有云有哪些模块?

随着全球化竞争的加剧和企业管理需求的日益复杂化&#xff0c;越来越多的企业开始采用云端企业资源计划&#xff08;ERP&#xff09;系统来优化业务流程。SAP ERP 公有云&#xff08;SAP S/4HANA Cloud, public edition&#xff09;作为一款领先的云端ERP解决方案&#xff0c;为…

nginx配置实例-动静分离

目录 一、相关概念 1.1动静分离概念 1.2动静分离的两种实现方法 二、实例配置 2.1 准备工作&#xff1a;在linux系统中准备静态资源&#xff0c;方便后面做测试 2.2 修改nginx配置文件 2.3 在浏览器测试 一、相关概念 1.1动静分离概念 将动态请求跟静态请求分开&#xf…

xgo: golang基于-toolexec实现猴子补丁

注&#xff1a; 转载请注明出处&#xff0c; 原文链接。 概述 在这篇博客中&#xff0c;我将详细介绍 xgo 的实现细节。 如果你不知道&#xff0c;xgo 项目位于 https://github.com/xhd2015/xgo。 它的作用很简单&#xff0c;就是在每个 Go 函数的开头添加拦截器&#xff0…

全志R128 SDK HAL 模块开发指南——IR红外无线传输

IR 红外是一种电磁波&#xff0c;可以实现数据的无线传输&#xff0c;由发送和接收两个部分组成。发送端对红外信号进行脉冲编码&#xff0c;接收端完成对红外信号的脉冲解码。红外遥控协议有多种&#xff0c;如 NEC、SIRC、 RC-5 等&#xff0c;这些协议都比较简单&#xff0…

【触想智能】工业一体机和普通电脑的区别是什么?

工业一体机和普通电脑的区别是什么&#xff0c;工业一体机可以当普通电脑一样使用吗? 要想了解工业一体机和普通电脑的区别是什么?我们首先来看看工业一体机是什么&#xff0c;它跟普通电脑有哪些相似的地方?下面小编就为大家来详细介绍一下。 在工作原理上&#xff0c;工业…

镭速集成SMTP开发邮件发送客户端

随着信息技术的不断进步&#xff0c;电子邮件已经成为商务交流和日常信息传递的关键工具。开发邮件客户端&#xff0c;尤其是整合了SMTP服务的客户端&#xff0c;对于增强企业内部的沟通效率和提升客户服务品质扮演着至关重要的角色。本文将深入探讨如何通过整合SMTP服务&#…

Linux系统Docker部署Apache Superset并实现公网实时访问本地数据

文章目录 前言1. 使用Docker部署Apache Superset1.1 第一步安装docker 、docker compose1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网穿透&#xff0c;实现公网访问3. 设置固定连接公网地址 前言 Superset是一款由中国知名科技公司开源的“现代化的…

基于springboot实现母婴商城管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现母婴商城系统演示 摘要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本母婴商城系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在…

Vue - 你知道Vue2中对象动态新增属性,视图无法更新的原因吗

难度级别:中高级及以上 提问概率:55% 这道题面试官会这样描述,比如有这样一个场景,一个对象里有name属性,可以正常显示在页面中。但后续动态添加了一个age属性,通过调试打印发现对象里的age属性已经添加了上了,但试图中却没有展示出来,…

pytest的时候输出一个F后面跟很多绿色的点解读

使用pytest来测试pyramid和kotti项目&#xff0c;在kotti项目测试的时候&#xff0c;输出一个F后面跟很多绿色的点&#xff0c;是什么意思呢&#xff1f; 原来在使用pytest进行测试时&#xff0c;输出中的“F”代表一个失败的测试&#xff08;Failed&#xff09;&#xff0c;而…

C#+net微信预约挂号系统源码,掌上医院挂号,在线缴费、检查、检验报告,住院服务

微信公众号预约挂号系统、支付宝小程序预约挂号系统主要是让自费、医保患者在手机上就能实现就医全过程&#xff0c;实时预约挂号、自费、医保结算&#xff0c;同时还可以查询检查检验报告等就诊信息&#xff0c;真正实现了让信息“多跑路”&#xff0c;让群众“少跑腿”。系统…