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 ...
随机推荐
- apache和nginx结合使用
1 有时候我们希望将nginx和apache结合起来使用,nginx接受用户的请求,作为请求转发服务器,apache作为后端服务器. 2 配置如下 nginx 中将80端口的请求转发到8000端口上 ...
- UVA140-Bandwidth(搜索剪枝)
Problem UVA140-Bandwidth Time Limit: 3000 mSec Problem Description Given a graph (V, E) where V is ...
- Google Colab 基本操作
## 上传 from google.colab import files uploaded = files.upload() for fn in uploaded.keys(): print('Use ...
- flashfxp软件设置并关联默认编辑器
flashfxp是一款优秀的ftp应用软件,作为程序员,有时候一点小的改动,在线编辑是很方便的选择,但是flashfxp自带的编辑器像记事本一样,非常不好用.那么怎么设置关联到本地的编辑器,比如设置成 ...
- 后端list集合中的数据传递到前台HTML中显示(表格形式)
关键字:web项目中前后台数据传递问题 在学习web项目的过程中,我们肯定会遇到前后台数据交换问题.这个问题我也思考了很久,今天借此总结一下.由于博主水平有限,如有不当之处,还请大家多多指正,,废话不 ...
- Docker网络和容器的通信
Docker的本地网络实现其实就是利用了Linux上的网络命名空间和虚拟网络设备(特别是veth pair). 基本原理 直观上看,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)与外界 ...
- NuGet的本地服务器安装与Package的发布(呕吐)
主要的步骤是按照下面的例子来做的: NuGet学习笔记(1)——初识NuGet及快速安装使用 NuGet学习笔记(2)——使用图形化界面打包自己的类库 NuGet学习笔记(3)——搭建属于自己的NuG ...
- 朱晔的互联网架构实践心得S1E2:屡试不爽的架构三马车
朱晔的互联网架构实践心得S1E2:屡试不爽的架构三马车 [下载本文PDF进行阅读] 这里所说的三架马车是指微服务.消息队列和定时任务.如下图所示,这里是一个三驾马车共同驱动的一个立体的互联网项目的架构 ...
- ECS上配置FTP Filezilla
又来搞华为ECS 第一,服务器安装服务端 第二,设置被动模式,把服务器的公网IP填好 第三,生成一个服务器证书,客户端连接时接受 第四,设置自定义的被动连接端口比如 9000-9050 第五,去ECS ...
- C#使用ILGenerator动态生成函数
游戏服务器里面总是有一大堆的配置文件需要读取, 而且这些配置文件的读取: * 要不然做成弱类型的, 就是一堆字符串或者数字, 不能看出来错误(需要重新检测一次) * 要不然做成强类型的, 每种类型都需 ...