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 ...
随机推荐
- [MCM] 多目标优化 MOP(multi-objective programming)
生活中许多问题都是由相互冲突和影响的多个目标组成.人们会经常遇到使多个目标在给定区域同时尽可能最佳的优化问题,也就是多目标优化问题.优化问题存在的优化目标超过一个并需要同时处理就成为多目标优化问题. ...
- 002_浅析python 中__name__ = '__main__' 的作用
很多新手刚开始学习python的时候经常会看到python 中__name__ = \'__main__\' 这样的代码,可能很多新手一开始学习的时候都比较疑惑,python 中__name__ = ...
- 6-MVC结构简介
一.javeEE的项目结构层次:MVC1.Model:模型层(DAO+业务层) 2.View:视图层 jsp3.Control:控制层 servlet 二.分层的原则:1.层与层之间松耦合,层内保持高 ...
- zookeeper的原理,5分钟了解zookeeper
一 .Zookeeper功能简介 ZooKeeper 是一个开源的分布式协调服务,由雅虎创建,是 Google Chubby 的开源实现.分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/ ...
- Python+Pycharm—学习—pip
1.pip是干什么的? 2.pip怎么安装? 3.pip怎么用?
- 一步一步写出java swing登录界面,以及输入的参数获取
经过好几天的学习,研究,接下来说说java swing,以及内嵌浏览器的方法. 一.swing是一个用于java应用程序用户界面的的开发工具包. 例如:接下来我们做个登录界面,简要说明 做之前的构想图 ...
- 工具篇-Java中一些utils
下边是整理的一些Java开发的utils,顺便吐槽下新浪博客的编辑器排版跟我写的博客一样 烂,所以改用博客园 一.字符串 1. Java中String与其他类型之间的转换 String与日期对象 pu ...
- WPF保存包含Winform控件的XAML页面问题
原文:WPF保存包含Winform控件的XAML页面问题 最近的工作中,用到了WPF调用Winform控件 但是在保存XAML页面的时候发现了问题,就是Winform页面黑黑的,没有任何渲染的波形曲线 ...
- 我的微软最有价值专家(Microsoft MVP)之路
一.写在前面 2018年对我来说是幸运的一年,对我来说最幸运的事情有两个,一个是在离驾照考试过期还有一个月(报名之后一直没去考)终于拿到了我的驾照,还有一件事莫过于获得了微软MVP.期间,一直有朋友问 ...
- Python—包介绍
包(Package) 当你的模块文件越来越多,就需要对模块文件进行划分,比如把负责跟数据库交互的都放一个文件夹,把与页面交互相关的放一个文件夹, . └── my_proj ├── crm #代码目录 ...