记录我对'我们有成熟的时间复杂度为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)的时间复杂度内找出数组中出现次数超过了一半的数
方法一:每次取出两个不同的数,剩下的数字中重复出现次数超过一半的数字肯定,将规模缩小化.如果每次删除两个不同的数,这里当然不是真的把它们踢出数组,而是对于候选数来说,出现次数减一,对于其他数来说,循环 ...
随机推荐
- DOM盒模型和位置 client offset scroll 和滚动的关系
DOM盒模型和位置 client offset scroll 和滚动的关系 概览 在dom里面有几个描述盒子位置信息的值, pading border margin width height clie ...
- 大白话Web三大组件之一Servlet
很多学习到Servlet这里的童鞋,听到那么多专业名词解释这个Servlet,相信都是很蒙圈的,在这里我先不跟大家扯Servlet的大概念,先跟大家探讨一下关于Servlet的作用 相信MVC这个概念 ...
- 使用spring中遇到"java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor"问题
项目中缺少aopalliance的jar包,下载一个相应的jar加入项目中就可以解决问题. 下载链接:http://www.java2s.com/Code/Jar/a/Downloadaopallia ...
- 2019 ICPC南京站网络赛 H题 Holy Grail(BF算法最短路)
计蒜客题目链接:https://nanti.jisuanke.com/t/41305 给定的起点是S,终点是T,反向跑一下就可以了,注意判负环以及每次查询需要添加边 AC代码: #include< ...
- codeforces 1189C Candies! / 前缀和
http://codeforces.com/problemset/problem/1189/C 求一下前缀和,给定区间的数字和除以10就是答案 AC代码: #include<iostream&g ...
- js Array 的所有方法
下面的这些方法会改变调用它们的对象自身的值: Array.prototype.copyWithin() 在数组内部,将一段元素序列拷贝到另一段元素序列上,覆盖原有的值. Array.prototyp ...
- IntelliJ IDEA 2017.3尚硅谷-----创建工程
- HDU 1326 Box of Bricks(思维)
Little Bob likes playing with his box of bricks. He puts the bricks one upon another and builds stac ...
- if a != None:
>>> x = 1 >>> not x False >>> x = [1] >>> not x False >>&g ...
- drf大总结
接口 """ 1.什么是接口:url+请求参数+响应数据 | 接口文档 2.接口规范: url:https,api,资源(名词复数),v1,get|post表示操作资源的 ...