LeetCode - 数组 - 四数之和

题目地址

描述

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。示例 1:输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]提示:1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109

思路

排序 + 双指针,能有效的提高遍历效率

本人题解

func fourSum(nums []int, target int) [][]int {// 排序sort.Slice(nums, func(i, j int) bool {return nums[i] < nums[j]})// 因为是四数之和,所以外边两层要通过遍历完成,内两层通过《排序 + 双指针 解两数之和》思路处理list := [][]int{}uniqueFlagMap := map[string]bool{}for i1 := 0; i1 < len(nums); i1++ {for i2 := i1 + 1; i2 < len(nums); i2++ {if l := twoSum(nums, i2+1, len(nums)-1, target-nums[i1]-nums[i2]); len(l) > 0 {for _, item := range l {// 因为不能出现重复结果,所以此处做了去重处理uniqueFlag := fmt.Sprintf("%d%d%d%d", nums[i1], nums[i2], nums[item[0]], nums[item[1]])if !uniqueFlagMap[uniqueFlag] {uniqueFlagMap[uniqueFlag] = truelist = append(list, []int{nums[i1], nums[i2], nums[item[0]], nums[item[1]]})}}}}}return list
}// 求有序数组两数之和方法
func twoSum(nums []int, i3, i4, target int) [][]int {list := [][]int{}for i3 < i4 {t := nums[i3] + nums[i4]if t == target {list = append(list, []int{i3, i4})i3++} else if t > target {i4--} else {i3++}}return list
}

LeetCode提交后,得分极差
在这里插入图片描述

优质解法

然后找了得分靠前的一位大佬的解法,果然牛逼的解法是不走寻常路的,先上代码:

func fourSum(nums []int, target int) [][]int {sort.Slice(nums, func(i, j int) bool {return nums[i] < nums[j]})n := len(nums)var ans [][]intfor a := 0; a < n-3; a++ {if a > 0 && nums[a] == nums[a-1] {continue}if nums[a] + nums[a+1] + nums[a+2] + nums[a+3] > target {break}if nums[a] + nums[n-1] + nums[n-2] + nums[n-3] < target {continue}for b := a+1; b < n-2; b++ {if b > a+1 && nums[b] == nums[b-1] {continue}c := b+1d := n-1for c < d {cur := nums[a] + nums[b] + nums[c] + nums[d]if cur == target {ans = append(ans, []int{nums[a], nums[b], nums[c], nums[d]})c += 1d -= 1for c < d && nums[c] == nums[c-1] {c += 1}for c < d && nums[d] == nums[d+1] {d -= 1}} else if cur < target {c += 1} else {d -= 1}}}}return ans
}

此代码直接借鉴大佬的,有侵权的地方,联系小编

总结

经过对优质解法的分析,得出了以下几点结论:

1、小编的整体思路是没问题的,也就是 ”排序 + 双指针“
2、优质代码增加了以下几点处理:

  • 为了不做去重复处理,在遍历的过程中,就对有可能导致重复的数据做了处理。处理思路是因为数组已经做了排序,所以有可能导致重复结果的数据是挨在一起的,比如 [-1,-1,0,0,-2,-2],如果对第一个-1已经做了处理,第二个-1就不用做处理了,直接跳过即可
func fourSum(nums []int, target int) [][]int {sort.Slice(nums, func(i, j int) bool {return nums[i] < nums[j]})n := len(nums)var ans [][]intfor a := 0; a < n-3; a++ {// 跳过有可能导致重复结果的数据if a > 0 && nums[a] == nums[a-1] {continue}if nums[a] + nums[a+1] + nums[a+2] + nums[a+3] > target {break}if nums[a] + nums[n-1] + nums[n-2] + nums[n-3] < target {continue}for b := a+1; b < n-2; b++ {// 跳过有可能导致重复结果的数据if b > a+1 && nums[b] == nums[b-1] {continue}c := b+1d := n-1for c < d {cur := nums[a] + nums[b] + nums[c] + nums[d]if cur == target {ans = append(ans, []int{nums[a], nums[b], nums[c], nums[d]})c += 1d -= 1// 跳过有可能导致重复结果的数据for c < d && nums[c] == nums[c-1] {c += 1}// 跳过有可能导致重复结果的数据for c < d && nums[d] == nums[d+1] {d -= 1}} else if cur < target {c += 1} else {d -= 1}}}}return ans
}
  • 对有序数组做掐头去尾处理
 for a := 0; a < n-3; a++ {// 去尾处理if nums[a]+nums[a+1]+nums[a+2]+nums[a+3] > target {break}// 掐头处理if nums[a]+nums[n-1]+nums[n-2]+nums[n-3] < target {continue}
}

经过这两步的优化,极大程度降低了遍历的次数,同时也缩短了每次遍历的耗时,所以整体上优化了耗时

在这里插入图片描述

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

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

相关文章

python从入门到精通02

一、平均油耗计算 total float(input("请输入加油的总金额&#xff1a;")) kilometers int(input("请输入行驶的总里程&#xff1a;")) average total / kilometers print("平均油耗是&#xff1a;", average,"元/公里") 二、华氏…

删除当前磁盘空文件夹小工具

删除当前磁盘空文件夹小工具 chcp 65001 >nulecho off setlocal EnableDelayedExpansionecho 正在扫描空文件夹&#xff0c;请稍候...for /f "delims" %%d in (dir /ad /b /s "\*") do (set "folder%%d"dir /a /b "!folder!" | fi…

个人学习之路

大学的时候在学校学习的是java&#xff0c;没有兴趣&#xff0c;且罢 快毕业了&#xff0c;为了工作学了C和C&#xff0c;每每也是在煎熬之中度过&#xff0c;总是否定自己&#xff0c;想要放弃又重新拾起来&#xff0c;做了相关的工作 后面换了工作&#xff0c;转到了python…

Spring IOC深度解析:IOC容器的原理与高级特性详解

1. Spring IOC容器概述 Spring框架是Java企业级应用开发中的重量级选手&#xff0c;其中IOC&#xff08;控制反转&#xff09;是其核心功能之一。通过引入IOC容器&#xff0c;Spring改变了对象的创建方式及其依赖关系的管理&#xff0c;进而带来了应用程序设计的革命。 1.1 什…

cs与msf权限传递以及mimikatz抓取win2012明文密码

简单的介绍 cs与msf的简单介绍 我查找过资料得出&#xff0c;Cobalt Strike 的前身是 Armitage&#xff0c;而 Armitage 又可以理解为 Metasploit Framework 的图形界面版&#xff0c;因此 Cobalt Strike 与 Metasploit Framework 在很多地方都是兼容的&#xff0c;所以我们便…

【电子信息(工程)】电子通信创新创业教育综合

电子通信创新创业教育 阐述电磁场、电磁波和电磁频谱及应用一、电磁场 法拉第根据电流与磁场的关系,提出了电磁感应定律:如果电磁场中有处于运动状态下的闭合回路导体存在,流经该导体磁场的磁场强度和磁场量,通常都会出现相应的变化,电磁感应电流由此而产生。随后,英国的…

人工智能 框架 paddlepaddle 飞桨 使用指南 使用例子 线性回归模型demo 详解

安装过程&使用指南&线性回归模型 使用例子 本来预想 是安装 到 conda 版本的 11.7的 但是电脑没有gpu 所以 安装过程稍有变动,下面简单讲下 conda create -n paddle_env117 python=3.9 由于想安装11.7版本 py 是3.9 所以虚拟环境名称也是 paddle_env117 activa…

下载和安装AD19 - Altium Designer 19.1.9 Build 167

虽然有AD24 的安装资源&#xff0c;但是我比较喜欢19 这个数字[doge] 下载 仍然是从毛子网站源头进货&#xff1a;https://rutracker.net/forum/viewtopic.php?t5754276&#xff0c;网盘: https://pan.baidu.com/s/1ic31N4h7HS2FBu7JFll0YQ?pwdvjum 提取码: vjum 安装 压…

如何用pyecharts工具制作地图

# # 导入地图构建使用的包 # from pyecharts.charts import Map # from pyecharts.options import VisualMapOpts # # # 创建一个地图 # China_map Map() # # # 给地图准备数据 # data [ # ("北京市", 100), # ("上海市", 95), # ("深圳…

【DevOps】深入了解RabbitMQ:AMQP协议基础、消息队列工作原理和应用场景

目录 一、核心功能 二、优势 三、核心概念 四、工作原理 五、交换机类型 六、消息确认 七、持久性和可靠性 八、插件和扩展 九、集群和镜像队列 十、客户端库 十一、管理界面 十二、应用场景 RabbitMQ是一个基于AMQP协议的消息队列中间件&#xff0c;提供高可用、可…

[MRCTF2020]Xor

32位程序 主要逻辑 flagMSAWB~FXZ:J:tQJ"N bpdd}8g for i in range(len(flag)):print(chr(ord(flag[i])^i),end)

react 权限树形结构实现

项目背景 react ant design 实现效果 1 将后台返回的平铺数据 , 转成树形结构 const [roleId, setRoleId] useState() //存储角色id// 弹权限弹窗const empowerHandle async record > {setRoleId(record.roleId)//获取单独的权限const res1 await getPermission({ role…

Java中线程调度与进程调度全解析

1.线程调度与进程调度的基本概念 1.1 什么是线程调度 线程调度是计算机多线程操作系统中分配CPU时间给各个线程的过程。每个线程代表程序中的一个执行路径&#xff0c;操作系统通过线程调度器分配处理器时间&#xff0c;决定哪个线程将获得执行的机会&#xff0c;以及获得的时…

力扣96. 不同的二叉搜索树

Problem: 96. 不同的二叉搜索树 文章目录 题目描述思路复杂度Code 题目描述 思路 一个数字做根节点的话可能的结果为&#xff1a;其左边数字做子树的组合数字乘以其右边数字做子树的个数之积 1.创建备忘录memo&#xff1b; 2.递归分别求取当前数字左边和右边数字做子树的数量&…

Vue 中 diff 算法原理

1. Diff 概念 vue 基于虚拟 DOM 做更新 。diff 的核心就是比较两个虚拟节点的差异 。Vue 的 diff 算法是平级比较,不考虑跨级比较的情况。内部采用深度递归的方式 + 双指针的方式进行比较。 2. Vue2 Diff 比较流程. 1.1先比较是否是相同节点 key tag 1.2相同节点比较属性,并…

【数据结构与算法 刷题系列】移除链表元素

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;数据结构与算法刷题系列&#xff08;C语言&#xff09; 期待您的关注 目录 一、问题描述 二、解题思路 三、源代码实现 一、问题…

phpstudy配置网站伪静态

apache的伪静态写法&#xff1a; RewriteEngine On RewriteCond % {REQUEST_FILENAME} !-f RewriteCond % (REQUEST_FILENAME) !-d RewriteRule ^(.*)$ indexp?/$1 [QSA, PT,L] nginx写法&#xff1a; location / { index index.html index.php; #autoindex on; if(!…

V2P(车与人)简介

V2P&#xff08;车与人&#xff09;简介 一、定义与概述 V2P&#xff08;Vehicle-to-Pedestrian&#xff09;是车联网&#xff08;V2X&#xff09;技术的一个重要组成部分&#xff0c;指的是车辆与行人之间的通信技术。它基于专用短波通讯DSRC或LTE-V等方式&#xff0c;实现车…

【MySQL精通之路】InnoDB静态数据加密(13)

目录 1.关于静止数据加密 2.加密先决条件 3.为库和通用表空间定义加密默认值 4.FPT表空间加密 5.通用表空间加密 6.Doublewrite文件加密 7.mysql系统表空间加密 8.redolog日志加密 9.undolog日志加密 10.主密钥轮转 11.加密和恢复 12.导出加密的表空间 13.加密和复…