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,一经查实,立即删除!

相关文章

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 安装 压…

【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…

力扣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; 期待您的关注 目录 一、问题描述 二、解题思路 三、源代码实现 一、问题…

基于trunk、yew构建web开发脚手架

trunk 构建、打包 rust wasm 程序&#xff1b;yewweb 前端开发库&#xff1b; 项目仓库yew-web trunk 之前已经简单介绍了trunk,全局安装&#xff1a; $> cargo install --locked trunk常用命令&#xff1a; trunk build 基于wasm-bindgen构建 wasm 程序。trunk watch …

vue17:v-bind对css样式的控制增强

代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><styl…

『USB3.0Cypress』FPGA开发(3)GPIF II短包零包时序分析

文章目录 1.时序参数2.FX3_PCLK3.短包和零包3.1短包时序3.2零包ZLP时序 4.传送门 1.时序参数 AN65974文档中明确了操作GPIF II接口时的时序参数&#xff0c;上一篇文章中给出了读写时序图&#xff0c;本篇第二节给出ZLP写周期时序&#xff0c;这里说明相关的时序参数。应该注意…

用户态下屏蔽全局消息钩子 —— ClientLoadLibrary 指针覆盖

目录 前言 一、研究 SetWindowsHookEx 的机制 二、概念验证 三、运行效果分析 四、总结与展望 参考文献 原文出处链接&#xff1a;[https://blog.csdn.net/qq_59075481/article/details/139206017] 前言 SetWindowsHookEx 函数帮助其他人员注入模块到我们的进程&#x…

【代码随想录训练营】【Day 27 and 28】【回溯1-2】| Leetcode 77, 216, 17

【代码随想录训练营】【Day 27 and 28】【回溯1-2】| Leetcode 77, 216, 17 需强化知识点 组合问题&#xff1a;感受遍历的横向和纵向 题目 77. 组合 注意path要深拷贝 class Solution:def combine(self, n: int, k: int) -> List[List[int]]:result []def backtrac…

Kubernetes(k8s) v1.30.1 本地集群部署 安装metallb 支持LoadBalancer 生产环境 推荐 BGP模式部署

1 metallb 安装参考:Kubernetes(k8s) v1.30.1 本地集群部署 默认不支持LoadBalancer metallb来解决-CSDN博客 2 删除 Layer 2 模式 配置 kubectl delete -f IPAddressPool.yaml kubectl delete -f L2Advertisement.yaml kubectl delete -f discuz-srv.yaml 3 配置 k8s Metal…

nacos-opera(k8s)安装问题解决

整理一些关于k8s部署nacos出现的一些恶心的问题 网上说其他说的更改数据库连接都未解决。 在用nacos-opera想安装高可用nacos时连接mysql数据库报错: 报错具体项: No DataSource set 具体就是说没找到数据源。 第一个 检查一下nacos连接数据库配置 : 第二个 检查一下数据库…

[笔试训练](三十三)097:跳台台阶扩展问题098:包含不超过两种字符的最长子串099:字符串的排列

目录 097:跳台台阶扩展问题 098:包含不超过两种字符的最长子串 099:字符串的排列 097:跳台台阶扩展问题 题目链接:跳台阶扩展问题_牛客题霸_牛客网 (nowcoder.com) 题目&#xff1a; 题解&#xff1a; 规律题: 1.跳上n级台阶的跳法等于前面1~(n-1)级台阶跳法的总和1。 2.跳…

一、机器学习概述

1.课程目的 学习机器学习算法、提高算法性能的技巧 2.算法分类 有监督学习supervised learning、无监督学习unsupervised learning (1).有监督学习 在这种学习方式中&#xff0c;算法需要一个带有标签的训练数据集&#xff0c;这些标签通常是每个样本的真实输出或类别。 在有…

NDIS小端口驱动(九)

PCIe设备难免会遇到一些重置设备的请求&#xff0c;例如重置总线的时候&#xff0c;但是由于NIC网卡的多样性&#xff0c;重置设备确实也有许多要注意的地方&#xff0c;另外还有一些包含WDM的NDIS驱动 微型端口驱动程序硬件重置 微型端口驱动程序必须向 NdisMRegisterMinipo…