记录我对'我们有成熟的时间复杂度为O(n)的算法得到数组中任意第k大的数'的误解
这篇博客记录我对剑指offer第2版"面试题39:数组中出现次数超过一半的数字"题解1的一句话的一个小误解,以及汇总一下涉及partition算法的相关题目。
在剑指offer第2版"面试题39:数组中出现次数超过一半的数字"的解法一(基于partition,且哨兵选择数组第一个元素)中,有这么一句话:
我们有成熟的时间复杂度为O(n)的算法得到数组中任意第k大的数字,这句话让我产生了一点误解,让我误以为"只需要调用一次partition就能找到第k大的数",但是实际上最差情况下需要调用n次partition函数才能找到第k大的数。因为partition每次都返回的是哨兵的位置,但是在函数运行过程中,随着l,r入参的变化,哨兵(数组首位元素)的位置是随之变化的,具有不确定性。
所以基于partition获取数组中任意第k大元素的时间复杂度应该如下:
- 最好时间复杂度 O(1) : 第一次循环就找到正确的哨兵(即,第k大元素)
- 最差时间复杂度 n*O(n): 最后一次才找到正确的哨兵
- (加权)平均复杂度 这个我不太会算,估计是O(n)
估算过程:
3.1 加权平均复杂度 = 某概率值*O(n)
3.2 概率值是常数,然后去掉常数项,得O(n)
partition的Go代码如下:
// partition代码的时间复杂度是O(n),因为需要通过for循环遍历数组,并把每个元素都划分到大分区或小分区中。
func partition(nums []int, l, r int) int {
// 1. 哨兵 取第一个元素
v := nums[l]
// 2. 大小分区的定义和初始化 [l+1,p]<v && [p+1,cur-1]>v
p := l
// 3. 处理哨兵之后的每一个元素
cur := l + 1
for ; cur <= r; cur++ {
if nums[cur] < v {
nums[cur], nums[p+1] = nums[p+1], nums[cur]
p++
}
}
nums[p], nums[l] = nums[l], nums[p] // 哨兵和小分区的最后一个元素交换,使得哨兵左边是小的,右边是大的.
return p
}
另外,还有以下这些算法题涉及了partition函数的运用,他们的共同特点都是需要用partition查找xxx位置的数字。
- Majority Element(本博客讨论的题) : partition查找m位置的数(中位数:索引为n/2)
- Kth Largest Element in an Array : partiton查找k位置的数
- 剑指offer面试题40:最小的k个数 : partiton查找k位置的数,但是只返回k位置左边的数,也就是小于哨兵的那些数
记录我对'我们有成熟的时间复杂度为O(n)的算法得到数组中任意第k大的数'的误解的更多相关文章
- 从数组中任意取出2个数,判断他们的和是否为输入的数字sum,时间复杂度为0(n^2),空间复杂度0(1)
从数组中任意取出2个数,判断他们的和是否为输入的数字sum,时间复杂度为0(n^2),空间复杂度0(1) 假设数据已经是排序好的 #include <stdio.h> #include & ...
- 求数组中的最小子数组,时间复杂度o(n),java
石家庄铁道大学 信1405-1 班 唐炳辉 题目:给定一个整数数组,找到一个具有最小和的子数组.返回其最小和. 设计思路:两个变量 ,一个记录当前并入的数组的值,另外一个记录所算过得最大的数组的值,当 ...
- 某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C/C++代码求出这两个单身整数。 要求: 时间复杂度o(n), 空间复杂度o(1)------某公司招聘试题
先看看这个题目:某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C代码求出这两个单身整数. 要求: 时间复杂度o(n), 空间复杂度o(1). 我们先用最傻瓜的方式来做吧: #inc ...
- 在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1)
题目:在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1) 分析:这道题考察位操作:异或(^),按位与(&),移位操作(>> ...
- 用O(1)的时间复杂度,找到栈和队列中的最小(大)值
最近刷剑指offer,看到两道编程题,考察在O(1)的复杂度内,找出最值. 觉得很有意思,很有借鉴意义,故记录在此. 需要注意的是,这里所说的O(1) 有个前提, 就是已经通过某种容器的存储方式进行初 ...
- 给定一数组,输出满足2a=b(a,b代表数组中的数)的数对,要求时间复杂度尽量低。
//时间复杂度O(n),空间复杂度O(n) void findSequence(int* arr, int len) { int* hashtable = new int[RANGE]; memset ...
- pig中查询top k,返回每个hour和ad_network_id下最大两个记录(SUBSTRING,order,COUNT_STAR,limit)
pig里面是有TOP函数,不知道为什么用不了.有时间要去看看pig源码了. SET job.name 'top_k'; SET job.priority HIGH; --REGISTER piggyb ...
- 查找数组中重复的唯一元素+时间复杂度O(n)+空间复杂度O(1)
这是我BIGO前端面试时,面试官给我出的一道题,题目是长度为N的数组,元素大小范围在[1,N-1],只有一个重复的元素,用O(n)的时间复杂度和O(1)的空间复杂度找出来这个重复的元素, 大致思路 1 ...
- 如何在O(n)的时间复杂度内找出数组中出现次数超过了一半的数
方法一:每次取出两个不同的数,剩下的数字中重复出现次数超过一半的数字肯定,将规模缩小化.如果每次删除两个不同的数,这里当然不是真的把它们踢出数组,而是对于候选数来说,出现次数减一,对于其他数来说,循环 ...
随机推荐
- HTML文字标签
<h1>标题标签,总共六个等级,不能创造标签,只有预定义好的标签才可以被浏览器解析 <br>换行标签,没有内容可以修饰也称为空标签 <p>段落标签</p> ...
- 一、centos7更改网卡名称eth0
异步赠书:10月Python畅销书升级 [线路图]人工智能到底学什么?! 程序员10月书讯 每周荐书(京东篇):618取胜之道.质量保障.技术解密) Centos7更改网卡名称Eth0 标签: Cen ...
- 代码反向生成数据库注释更新sql
原理 通过反射实体所在程序集,得到枚举值列表,再通过sql获取数据库表结构,两者拼接成sql. 规范 实体枚举字段最好也加上Description特性,方便多次更新: 代码 实体定义 public p ...
- mybatis(六):设计模式 - 责任链模式
- 常见python面试题
1,简述列举了解的编程语言及语言间的区别? Python 解释型语言,代码简洁,易懂 C语言 编译型语言,底层语言 c++ 编译型语言,在C语言基础上加了面向对象 Java 混合型语言,可拓展性高 G ...
- bugku 有一张图,还单纯吗
下载图片后以多种方式打开.分析文件类型都没能找到flag.推测存在隐藏文件,即文件可分离. 注:文件分离需要 binwalk 工具,在Ubuntu操作系统下 binwalk 的安装方法可参考此博客:h ...
- CI框架Email类发送邮件提示Unable to send data: . The following SMTP error was encountered: Unable to .......
最近服务器迁移,然后CI框架做的项目发邮件全挂掉了,刚开始是25端口没开,然后开了正好还是有问题, 1.打印请求信息和返回信息 echo $this->email->print_debug ...
- deepin linux 安装之后 引导错误 出现 grub>
deepin 安装之后 引导错误 ,,, 忙了一晚上 终于解决了 太辛苦了 不过明白了grub的工作原理也不亏,,,, 就是 整个过程满满的绝望 (哭 环境说明 华硕顽石4 笔记本 硬盘分区表GPT ...
- [Netcat] 断线重连 自动重连
今天想做些操作,所以想到了nc 但是nc太过于轻量级 所以 导致我没有找到他的断线重连功能 然后我就想到了windows的神器之一 vbs脚本 vbs代码如下 Dim a,b set a= WScri ...
- HDU4714 Tree2cycle 解题报告
题意 给定一棵无根树,删除或连接一条边的代价为\(1\),求把树变为环的最小代价. 前置思路 如果删除了\(k\)条边,使得树变成\((k+1)\)条链,再用\((k+1)\)次连接操作把树变成一个环 ...