Partition算法以及其应用详解下(Golang实现)
接前文,除了广泛使用在快速排序中。Partition算法还可以很容易的实现在无序序列中使用O(n)的时间复杂度查找kth(第k大(小)的数)。
同样根据二分的思想,每完成一次Partition我们可以轻松的知道该位置前面有几个比自己小的数,后面有几个比自己大的数(或逆序相反)。所以也能知道自己是第几大或者小的数。
查找kth(大/小)
func partition(left int, right int, arr []int) (int) {
i := left
j := right
pivot := arr[left]
for i != j {
for i < j && arr[j] >= pivot {
j--
} for i < j && arr[i] <= pivot {
i++
} if i < j{
arr[i], arr[j] = arr[j], arr[i]
}
}
arr[left], arr[i] = arr[i], arr[left]
return i
} func findKthSmallestNumber(arr[]int, k int) (int) {
left := 0
right := len(arr)-1
targetNumber := 0
for left <= right {
pos := partition(left, right, arr)
if pos == k-1 {
targetNumber = arr[pos]
break
} else if pos > k-1 {
right = pos - 1
} else {
left = pos + 1
}
}
return targetNumber
} func main() {
list := []int{4, 3, 1, 4, 5, 6, 3}
fmt.Println(findKthSmallestNumber(list, 6))
}
逻辑是每次partition回传的位置,都是分割好的位置。
那么我们假设默认pivot设置的数总是操作数组(假如是按照正序排列,即比pivot大的数放右边,比pivot小的数放左边)的第一个数。分割完毕后,我们拿着回传的pivot位置同要寻找的k小的数做比较。
如果 pivot = k-1 那么说明这就是我们要找的那个位置,直接返回即可。pivot返回的是索引位置,比如我们要找第二小的数,索引位置就应该是1。
如果 pivot > k-1 那么说明我们要找的数在pivot的左边,这时我们需要将right置为pos索引-1
如果 pivot < k-1 那么说明我们要找的数载pivot的右边,这时我们需要将left的值置为pos索引+1
另外特别要注意的一点就是边界的问题。由于上面我使用的例子中right就是传递的索引的终点为之,所以left是有可能等于right的情况的,这时要让程序进入循环正确退出。如果你使用的是len数量版本的partition算法,就不需要这样做。
Dutch national flag problem:
荷兰国旗问题,同样是经典的Partition算法的问题。通过一次扫描来进行归类,依然是他核心思想。解决这个问题我们除了要同时使用头部指针,尾部指针以外。还需要使用一个当前位置的指针来扫描。
func threeWayPartition(list []int, target int) {
var smallestPos, scanPos int
biggestPos := len(list)-1 for scanPos <= biggestPos {
if list[scanPos] < target {
list[scanPos], list[smallestPos] = list[smallestPos], list[scanPos]
scanPos++
smallestPos++
} else if list[scanPos] > target {
list[scanPos], list[biggestPos] = list[biggestPos], list[scanPos]
biggestPos--
} else {
scanPos ++
}
}
}
首先扫描的当前位置只能小于和等于指向最大指针的位置。因为我们总是使用scanPos位置上的数来进行判断的,如果这里是小于而不是小于等于的话就意味着指向最大值的指针位置所在的值miss了。
说明这个之后,其他的就可以分为三种情况。
如果scanPos > target的话 就会跟后面指向大值的指针交换,然后大值指针往后退一
如果scanPos < target的话 就会跟前面指向小值的指针交换,然后当前指针位置和指向最小值的指针同进一
如果scanPos = target的话 当前指针继续往前,指向小值的指针会原地不动。
用心感受一下,其实还是蛮简单的。。
Partition算法以及其应用详解下(Golang实现)的更多相关文章
- Partition算法以及其应用详解上(Golang实现)
最近像在看闲书一样在看一本<啊哈!算法> 当时在amazon上面闲逛挑书,看到巨多人推荐这本算法书,说深入浅出简单易懂便买来阅读.实际上作者描述算法的能力的确令人佩服.就当复习常用算法吧. ...
- python 排序算法总结及实例详解
python 排序算法总结及实例详解 这篇文章主要介绍了python排序算法总结及实例详解的相关资料,需要的朋友可以参考下 总结了一下常见集中排序的算法 排序算法总结及实例详解"> 归 ...
- SSL/TLS协议详解(下)——TLS握手协议
本文转载自SSL/TLS协议详解(下)--TLS握手协议 导语 在博客系列的第2部分中,对证书颁发机构进行了深入的讨论.在这篇文章中,将会探索整个SSL/TLS握手过程,在此之前,先简述下最后这块内容 ...
- [js高手之路]深入浅出webpack教程系列3-配置文件webpack.config.js详解(下)
本文继续接着上文,继续写下webpack.config.js的其他配置用法. 一.把两个文件打包成一个,entry怎么配置? 在上文中的webpack.dev.config.js中,用数组配置entr ...
- SSD算法及Caffe代码详解(最详细版本)
SSD(single shot multibox detector)算法及Caffe代码详解 https://blog.csdn.net/u014380165/article/details/7282 ...
- 红黑树原理详解及golang实现
目录 红黑树原理详解及golang实现 二叉查找树 性质 红黑树 性质 operation 红黑树的插入 golang实现 类型定义 leftRotate RightRotate Item Inter ...
- 关联规则算法(The Apriori algorithm)详解
一.前言 在学习The Apriori algorithm算法时,参考了多篇博客和一篇论文,尽管这些都是很优秀的文章,但是并没有一篇文章详解了算法的整个流程,故整理多篇文章,并加入自己的一些注解,有了 ...
- SSD(single shot multibox detector)算法及Caffe代码详解[转]
转自:AI之路 这篇博客主要介绍SSD算法,该算法是最近一年比较优秀的object detection算法,主要特点在于采用了特征融合. 论文:SSD single shot multibox det ...
- CSS2.1SPEC:视觉格式化模型之width属性详解(下)
本文承接CSS2.1SPEC:视觉格式化模型之width属性详解(上),继续分析CSS视觉格式化模型中width以及相关值的计算问题: 注:与上节不同,本节的demo中由于出现了float,absol ...
随机推荐
- 查看linux内存使用情况
查看内存使用情况 free -m total used free shared buffers cached Mem: -/+ buffers/cache: Swap: used=total-free ...
- JWT(JSON Web Token)
摘要: 在Web应用中,使用JWT替代session并不是个好主意 适合JWT的使用场景 抱歉,当了回标题党.我并不否认JWT的价值,只是它经常被误用. 什么是JWT 根据维基百科的定义,JSON W ...
- 爬取伯乐在线文章(五)itemloader
ItemLoader 在我们执行scrapy爬取字段中,会有大量的CSS或是Xpath代码,当要爬取的网站多了,要维护起来很麻烦,为解决这类问题,我们可以根据scrapy提供的loader机制. 导入 ...
- python:while循环、运算符、初始编码
while循环 while -- 关键字 while 条件: 缩进代码块 以上循环是(死循环) 终止循环的方法 1.break 跳出循环,并且把循环给干掉了 2.continue 跳出本次循环,继续下 ...
- day96
在服务器上部署上线项目 Linux数据库处理 首先我们需要在mysql中创建bbs库,并导入数据库SQL脚本(就是原本运行在我们项目中的数据库) 前提:需要进入mysql中 mysql> cre ...
- rabbitMQ教程(五)rabbitmq 指令 以及解决web管理界面无法使用guest用户登录
安装最新版本的rabbitmq(3.3.1),并启用management plugin后,使用默认的账号guest登陆管理控制台,却提示登陆失败. 翻看官方的release文档后,得知由于账号gues ...
- immutability因React官方出镜之使用总结分享!
作者:首席填坑官∙苏南 公众号:honeyBadger8,群:912594095,本文原创,著作权归作者所有,转载请注明原链接及出处. 引言 之前项目中遇到数据拷贝.引用之间数据层级嵌套过深,拷贝的值 ...
- flask 更新数据库
在做项目的过程中,我们都遇到过,经常需要修改我们数据库的字段,在flask中,是通过ORM(对象关系映射)来创建数据库的,表--->model class,字段---->属性 在flask ...
- Python_每日习题_0004_一年中的第几天
# 题目 输入某年某月某日,判断这一天是这一年的第几天? # 程序分析 特殊情况,闰年时需考虑二月多加一天: def isLeapYear(y): return (y%400==0 or (y%4== ...
- Survey项目总结
1.Ioc深入理解 Inverse of control org.springframework.scheduling.quartz.SchedulerFactoryBean org.mybatis. ...