算法篇:二分法之k个数之和
时间:2022-07-24
本文章向大家介绍算法篇:二分法之k个数之和,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
算法:
这类题目是二分法的典型题目,核心点就是实现二数之和,三数之和,四数之和,多数之和都属于这类题目的变形题目。本文章统一整理了一个套路,多数之后最终转化为二数之和,通过递归来获取结果。基本步骤如下:
1.先将无序的数组排序。
2.按照典型的二数之和算法求解两数之和。
3.将多数之和,采用递归的方式最终用两数之和计算结果。
题目1: 两数之和
https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/
代码实现:
func twoSum(numbers []int, target int) []int {
l := len(numbers)
if l == 0 {
return nil
}
start, end:= 0, l-1
var tar []int
for start < end {
sum := numbers[start] + numbers[end]
if sum == target {
tar = append(tar,start+1)
tar = append(tar,end+1)
return tar
} else if sum > target {
end --
} else {
start++
}
}
return tar
}
执行结果:
题目2:三数之和
https://leetcode-cn.com/problems/3sum/
代码实现:
func threeSum(nums []int) [][]int {
sort.Ints(nums)
res := [][]int{}
for i:=0;i<len(nums);i++{
arr := nums[i+1:]
r := twoSum(arr,0-nums[i])
if r!=nil {
for _,v:=range r {
tmp := []int{nums[i]}
tmp = append(tmp,v...)
res = append(res,tmp)
}
}
for i+1 < len(nums)-1 && nums[i]==nums[i+1] {
i++
}
}
return res
}
func twoSum(nums []int, sum int) (res [][]int) {
i,j:=0,len(nums)-1
for i<j {
if nums[i]+nums[j]<sum {
i++
} else if nums[i]+nums[j]>sum {
j--
} else {
tmp := []int{nums[i], nums[j]}
res = append(res, tmp)
for i+1<j && nums[i+1] == nums[i] {
i++
}
for j-1>i && nums[j-1] == nums[j] {
j--
}
i++
j--
}
}
return
}
执行结果:
题目3:四数之和
https://leetcode-cn.com/problems/4sum/
代码实现:
func fourSum(nums []int, target int) [][]int {
var res [][]int
if len(nums) < 4 {
return res
}
sort.Ints(nums) // 排序
res = findNSum(nums, target, 4)
return res
}
func findNSum(nums []int, target int, n int) [][]int {
var res [][]int
// 当nums不足2个数时,返回空的res
if len(nums) < 2 || n < 2 {
return res
}
i,j := 0,len(nums)-1
if n == 2 {
for i < j {
sum := nums[i] + nums[j]
if sum < target {
i++
} else if sum > target {
j--
} else {
tmp := []int{nums[i], nums[j]}
res = append(res, tmp)
// 这后面是为了去除重复数据,
// 例如,a,a,a,a,b,后面的a+b其实已经重复了,所以只需要偏移,
// 不需要再次添加到res集合中。
for i + 1 < j && nums[i+1] == nums[i] {
i++
}
for j - 1 > i && nums[j-1] == nums[j] {
j--
}
// 进一步缩小数组的范围,看还存不存在另外一种组合相同
i++
j--
}
}
} else {
// 当n > 2时,遍历数组每一个元素,求基于当前数的 n - 1个数之和的全集
for i := 0; i < len(nums) - 1; i++ {
arr := nums[i+1:]
// 数组为去除当前元素,target为减去当前值,n需要减1
resTmp := findNSum(arr, target-nums[i], n-1)
// 当找到resTmp结果时,加入结果集
if len(resTmp) != 0 {
for _, v := range resTmp {
tmp := []int{nums[i]}
tmp = append(tmp, v...) // 合并当前数和除去该数之后的其他数集合
res = append(res, tmp) // 存入单次计算结果
}
}
// 去除重复数据,相同数字只算一次,例如 [a,a,a,a,b]跳过重复的a到b
for i + 1 < len(nums) - 1 && nums[i+1] == nums[i] {
i++
}
}
}
return res
}
执行结果:
- Golang语言中Path包用法
- 100个Numpy练习【5】
- Golang中container/list包中的坑
- 关于Golang语言数组索引的有趣现象
- 使用SQL来分析数据库参数(二)(r10笔记第82天)
- Golang不定参数
- [go语言]利用缓冲信道来实现网游帐号验证消息的分发和等待
- 转--Golang语言版 ssh口令破解工具
- cubieboard(树莓派)安装Ubuntu+Apache+PHP+Mysql
- Oracle 12c里的几点补充(一)(r11笔记第7天)
- Oracle备库的PDB无法连接的问题(r11笔记第6天)
- Golang语言社区--模板的使用
- Golang语言写Web 应用程序
- 强制wordpress后台HTTPS
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 可怕的万圣节 Linux 命令
- linux环境不使用hadoop安装单机版spark的方法
- 在linux下玩转带有超时时间的connect函数
- Linux/CentOS服务器安全配置通用指南
- 详解centos7中配置keepalived日志为别的路径
- jointplot快速探究两组变量的分布及关系
- linux中alarm函数的实例讲解
- 如何给Linux虚拟机连上WiFi详解
- Linux系统查看CPU、机器型号、内存等信息
- 实战基本的Linux sed命令示例代码
- 在Linux中如何查看可用的网络接口详解
- Linux程序运行时加载动态库失败的解决方法
- Linux/CentOS系统同步网络时间的2种方法详解
- Linux 常用命令之Linux more命令使用方法
- Ubuntu下VIM配置成C++开发编辑器