这篇博客记录我对剑指offer第2版"面试题39:数组中出现次数超过一半的数字"题解1的一句话的一个小误解,以及汇总一下涉及partition算法的相关题目。

在剑指offer第2版"面试题39:数组中出现次数超过一半的数字"的解法一(基于partition,且哨兵选择数组第一个元素)中,有这么一句话:

我们有成熟的时间复杂度为O(n)的算法得到数组中任意第k大的数字,这句话让我产生了一点误解,让我误以为"只需要调用一次partition就能找到第k大的数",但是实际上最差情况下需要调用n次partition函数才能找到第k大的数。因为partition每次都返回的是哨兵的位置,但是在函数运行过程中,随着l,r入参的变化,哨兵(数组首位元素)的位置是随之变化的,具有不确定性。

所以基于partition获取数组中任意第k大元素的时间复杂度应该如下:

  1. 最好时间复杂度 O(1) : 第一次循环就找到正确的哨兵(即,第k大元素)
  2. 最差时间复杂度 n*O(n): 最后一次才找到正确的哨兵
  3. (加权)平均复杂度 这个我不太会算,估计是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位置的数字。

  1. Majority Element(本博客讨论的题) : partition查找m位置的数(中位数:索引为n/2)
  2. Kth Largest Element in an Array : partiton查找k位置的数
  3. 剑指offer面试题40:最小的k个数 : partiton查找k位置的数,但是只返回k位置左边的数,也就是小于哨兵的那些数

记录我对'我们有成熟的时间复杂度为O(n)的算法得到数组中任意第k大的数'的误解的更多相关文章

  1. 从数组中任意取出2个数,判断他们的和是否为输入的数字sum,时间复杂度为0(n^2),空间复杂度0(1)

    从数组中任意取出2个数,判断他们的和是否为输入的数字sum,时间复杂度为0(n^2),空间复杂度0(1) 假设数据已经是排序好的 #include <stdio.h> #include & ...

  2. 求数组中的最小子数组,时间复杂度o(n),java

    石家庄铁道大学 信1405-1 班 唐炳辉 题目:给定一个整数数组,找到一个具有最小和的子数组.返回其最小和. 设计思路:两个变量 ,一个记录当前并入的数组的值,另外一个记录所算过得最大的数组的值,当 ...

  3. 某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C/C++代码求出这两个单身整数。 要求: 时间复杂度o(n), 空间复杂度o(1)------某公司招聘试题

    先看看这个题目:某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C代码求出这两个单身整数. 要求: 时间复杂度o(n), 空间复杂度o(1). 我们先用最傻瓜的方式来做吧: #inc ...

  4. 在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1)

    题目:在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1) 分析:这道题考察位操作:异或(^),按位与(&),移位操作(>> ...

  5. 用O(1)的时间复杂度,找到栈和队列中的最小(大)值

    最近刷剑指offer,看到两道编程题,考察在O(1)的复杂度内,找出最值. 觉得很有意思,很有借鉴意义,故记录在此. 需要注意的是,这里所说的O(1) 有个前提, 就是已经通过某种容器的存储方式进行初 ...

  6. 给定一数组,输出满足2a=b(a,b代表数组中的数)的数对,要求时间复杂度尽量低。

    //时间复杂度O(n),空间复杂度O(n) void findSequence(int* arr, int len) { int* hashtable = new int[RANGE]; memset ...

  7. 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 ...

  8. 查找数组中重复的唯一元素+时间复杂度O(n)+空间复杂度O(1)

    这是我BIGO前端面试时,面试官给我出的一道题,题目是长度为N的数组,元素大小范围在[1,N-1],只有一个重复的元素,用O(n)的时间复杂度和O(1)的空间复杂度找出来这个重复的元素, 大致思路 1 ...

  9. 如何在O(n)的时间复杂度内找出数组中出现次数超过了一半的数

    方法一:每次取出两个不同的数,剩下的数字中重复出现次数超过一半的数字肯定,将规模缩小化.如果每次删除两个不同的数,这里当然不是真的把它们踢出数组,而是对于候选数来说,出现次数减一,对于其他数来说,循环 ...

随机推荐

  1. 慎用--skip-grant-tables命令

    该命令作用是跳过授权表,也就是说谁都能进入mysql看到所有数据表,输入任意字符账号密码都可以 当忘记账号密码时可以使用改命令修改密码,但是要随用随关,重启mysql,不然服务器上会有很大的风险. 介 ...

  2. python之路之线程,进程,协程2

    一.线程 1.创建线程 2.主线程是否等待子线程 t.setDaemon(Ture/False):默认是false,等待子线程完成,ture,表示不等待子线程结束 3.主线程等待,子线程执行 join ...

  3. .net c# MVC提交表单的4种方法

    https://blog.csdn.net/qingkaqingka/article/details/85047781

  4. apache http server 和tomcat的区别 以及nginx

    Apache HTTP Server(简称Apache)是Apache软件基金会的一个开放源码的网页服务器. 要明白他们之间的区别,我们首先需要明白HTTP协议.HTML页面.JSP.Servlet之 ...

  5. 10.4.3反向迭代器Reverse_iterator笔记

    反向迭代器就是在容器中从尾元素向首元素反向移动的迭代器.对于反向携带器,递增(以及递减)操作的含义会颠倒过来.递增一个反向迭代器(++it)会移动到前一个元素:递减一个迭代器(--it)会移动到下一个 ...

  6. [lua]紫猫lua教程-命令宝典-L1-01-09. string字符串函数库

    L1[string]01. ASCII码互转 小知识:字符串处理的几个共同的几点 1.字符串处理函数 字符串索引可以为负数 表示从字符串末尾开始算起 所有字符串处理函数的 字符串索引参数都使用 2.所 ...

  7. Centos7 FRPS

    #下载Sever端 wget https://github.com/fatedier/frp/releases/download/v0.16.1/frp_0.16.1_linux_amd64.tar. ...

  8. B. Game with string 思维问题转化

    B. Game with string 思维问题转化 题意 有一个字符串 每次可以删去连续的两个同样的字符,两个人轮流删,问最后谁能赢 思路 初看有点蒙蔽,仔细看看样例就会发现其实就是一个括号匹配问题 ...

  9. window10配置远程虚拟机window7上的mysql5.7数据源

    原文链接:http://www.xitongcheng.com/jiaocheng/win10_article_18644.html windows10系统用户想要在电脑中设置ODBC数据源,于是手动 ...

  10. Codeforces Global Round 3:B. Born This Way

    Born This Way原文链接:[传送门] 题目大意:潇洒哥想乘坐飞机从A地到达C地,但是没有直达的航班,在A地和B地之间有一个可以中转的航班B,潇洒哥想早点到达C地(有航班就坐),但是很不幸他得 ...