Golang 三数之和+ 四数之和 leetcode15、18 双指针法

2024-01-15 08:28

本文主要是介绍Golang 三数之和+ 四数之和 leetcode15、18 双指针法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 三数之和 leetcode15
    • map记录 失败!超出限制
    • 双指针法
  • 四数之和 leetcode18

三数之和 leetcode15

知识补充:

map的key值必须是可以比较运算的类型,不可以是函数、map、slice

map记录 失败!超出限制

//得到结果后再去重 失败!
func threeSum(nums []int) [][]int {L := len(nums)var intT stringresult := [][]int{}N := map[int]int{}G := map[string]int{}table := make([][]int, L)for i, _ := range table {table[i] = make([]int, L)}for i, v := range nums {N[v] = i}for i := 0; i < L-1; i++ {for c := i + 1; c < L; c++ {table[i][c] = nums[i] + nums[c]if index, ok := N[-table[i][c]]; ok {if index != i && index != c {order := []int{nums[i], nums[c], nums[index]}slices.Sort(order)for _, v := range order {intT = fmt.Sprintf(intT, string(rune(v)))}if _, cont := G[intT]; !cont {result = append(result, []int{nums[i], nums[c], nums[index]})}G[intT] = 1intT = ""}}}}// fmt.Print(table)return result
}

双指针法

拿这个nums数组来举例,首先将数组排序,然后有一层for循环,i从下标0的地方开始,同时定一个下标left 定义在i+1的位置上,定义下标right 在数组结尾的位置上。

依然还是在数组中找到 abc 使得a + b +c =0,我们这里相当于 a = nums[i],b = nums[left],c = nums[right]。

接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下标就应该向左移动,这样才能让三数之和小一些。

如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。

// 自我救赎的双指针法
func threeSum(nums []int) [][]int {
slices.Sort(nums)
L := len(nums)
record := [][]int{}//第一个数
for i, i2 := range nums[:L-2] {//左指针为第二个数,右指针为第三个数。左指针每次从第一个数后一个开始,右指针则从最末尾开始
left, right := i+1, L-1//第一个数的去重 ,如{-1 -1 0 1},[0,2,3]和[1,2,3]都满足要求,但是其数组都为[-1,0,1]应该去除之一。所以说当检测当本次循环与上次一致的话,直接跳过
if i > 0 && i2 == nums[i-1] {
continue
}//循环的结束条件为左指针与右指针重合,即第二个数和第三个数序号一致
for left < right {
if i2+nums[left]+nums[right] == 0 {
record = append(record, []int{i2, nums[left], nums[right]})
left++
right--//对第二个数进行去重
for nums[left] == nums[left-1] && left < L-1 {
left++
}//对第三个数进行去重
for nums[right] == nums[right+1] && right > 1 {
right--
}
}
if i2+nums[left]+nums[right] > 0 {
right--
}
if i2+nums[left]+nums[right] < 0 {
left++
}
}}
return record
}

四数之和 leetcode18

与三数之和思路大体相同,代码如下:

// 自我救赎的双指针法
func fourSum(nums []int, target int) [][]int {
slices.Sort(nums)
L := len(nums)
if L < 4 {
return nil
}record := [][]int{}//第一个数
for i, val := range nums[:L-3] {
if i > 0 && val == nums[i-1] {
continue
}//第二个数
for i2 := i + 1; i2 < L-2; i2++ {
val2 := nums[i2]
//左指针为第二个数,右指针为第三个数。左指针每次从第一个数后一个开始,右指针则从最末尾开始
left, right := i2+1, L-1//第一个数的去重 ,如{-1 -1 0 1},[0,2,3]和[1,2,3]都满足要求,但是其数组都为[-1,0,1]应该去除之一。所以说当检测当本次循环与上次一致的话,直接跳过
if i2 > i+1 && val2 == nums[i2-1] {
continue
}//循环的结束条件为左指针与右指针重合,即第二个数和第三个数序号一致
for left < right {
if val+val2+nums[left]+nums[right] == target {
record = append(record, []int{val, val2, nums[left], nums[right]})
left++
right--//对第二个数进行去重
for nums[left] == nums[left-1] && left < L-2 {
left++
}//对第三个数进行去重
for nums[right] == nums[right+1] && right > 2 {
right--
}
}
if val+val2+nums[left]+nums[right] > target {
right--
}
if val+val2+nums[left]+nums[right] < target {
left++
}
}}}return record
}

这篇关于Golang 三数之和+ 四数之和 leetcode15、18 双指针法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/608257

相关文章

Golang 日志处理和正则处理的操作方法

《Golang日志处理和正则处理的操作方法》:本文主要介绍Golang日志处理和正则处理的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录1、logx日志处理1.1、logx简介1.2、日志初始化与配置1.3、常用方法1.4、配合defer

Java空指针异常NullPointerException的原因与解决方案

《Java空指针异常NullPointerException的原因与解决方案》在Java开发中,NullPointerException(空指针异常)是最常见的运行时异常之一,通常发生在程序尝试访问或... 目录一、空指针异常产生的原因1. 变量未初始化2. 对象引用被显式置为null3. 方法返回null

golang float和科学计数法转字符串的实现方式

《golangfloat和科学计数法转字符串的实现方式》:本文主要介绍golangfloat和科学计数法转字符串的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望... 目录golang float和科学计数法转字符串需要对float转字符串做处理总结golang float

golang实现延迟队列(delay queue)的两种实现

《golang实现延迟队列(delayqueue)的两种实现》本文主要介绍了golang实现延迟队列(delayqueue)的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录1 延迟队列:邮件提醒、订单自动取消2 实现2.1 simplChina编程e简单版:go自带的time

Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)

《Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)》本文主要介绍了Golang分布式锁实现,采用Redis+Lua脚本确保原子性,持可重入和自动续期,用于防止超卖及重复下单,具有一定... 目录1 概念应用场景分布式锁必备特性2 思路分析宕机与过期防止误删keyLua保证原子性可重入锁自动

golang 对象池sync.Pool的实现

《golang对象池sync.Pool的实现》:本文主要介绍golang对象池sync.Pool的实现,用于缓存和复用临时对象,以减少内存分配和垃圾回收的压力,下面就来介绍一下,感兴趣的可以了解... 目录sync.Pool的用法原理sync.Pool 的使用示例sync.Pool 的使用场景注意sync.

golang中slice扩容的具体实现

《golang中slice扩容的具体实现》Go语言中的切片扩容机制是Go运行时的一个关键部分,它确保切片在动态增加元素时能够高效地管理内存,本文主要介绍了golang中slice扩容的具体实现,感兴趣... 目录1. 切片扩容的触发append 函数的实现2. runtime.growslice 函数gro

golang实现动态路由的项目实践

《golang实现动态路由的项目实践》本文主要介绍了golang实现动态路由项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习... 目录一、动态路由1.结构体(数据库的定义)2.预加载preload3.添加关联的方法一、动态路由1

Golang interface{}的具体使用

《Golanginterface{}的具体使用》interface{}是Go中可以表示任意类型的空接口,本文主要介绍了Golanginterface{}的具体使用,具有一定的参考价值,感兴趣的可以了... 目录一、什么是 interface{}?定义形China编程式:二、interface{} 有什么特别的?✅

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持