【Leetcode Top-K问题 BFPRT】第三大的数(414)
题目
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
示例 1:
输入: [3, 2, 1]
输出: 1
解释: 第三大的数是 1.
示例 2:
输入: [1, 2]
输出: 2
解释: 第三大的数不存在, 所以返回最大的数 2 .
示例 3:
输入: [2, 2, 3, 1]
输出: 1
解释: 注意,要求返回第三大的数,是指第三大且唯一出现的数。存在两个值为2的数,它们都排第二。
解答
思路:
1,题目要求时间复杂度必须是O(n),那么排序肯定是不行了,由于只是求第三大,那么可以先求出第一大,再求出第二大,再求第三大,总的时间复杂度O(N)。
2,BFPRT,专门解决TOP-K问题,但是因为序列中可能有重复值,所以在进行BFPRT之前,先去重,总的时间复杂度O(N)。
(2020.1.7更)
3,堆,大小为k的小顶堆,k=3。Time: N·log(k) = O(N), Space: O(1)
4,二叉排序树,首先构建一颗二叉排序树,中序遍历得出从小到大的序列,取第K大。构建二叉排序树平均log(N),最差O(N),查找第K大O(N)
5,AVL树,优化的二叉排序树,优化了构建二叉树的时间复杂度,最差log(N),中序遍历查找第K大O(N)
通过代码如下:
方法一
class Solution:
    def thirdMax(self, nums: List[int]) -> int:
        l = list(set(nums))
        max_list = []
        sum = min(3, len(l))
        while sum:
            max = -float('inf')  # 负无穷
            for x in l:
                if x > max and x not in max_list:
                    max = x
            if max not in max_list:
                # l.remove(max)  remove时间复杂度为O(n)
                del l[l.index(max)]
                max_list.append(max)
            sum -= 1
        return max_list[-1] if len(max_list)>=3 else max_list[0]
BFPRT
class Solution:
    def thirdMax(self, nums) -> int:
        k = 3  # 代表求第三大
        nums = list(set(nums))
        if len(nums) < 3:
            return max(nums)
        def getmedian(lis):
            """返回序列lis中位数,在BFPRT中就是求每5个数小组的中位数"""
            begin = 0
            end = len(lis) - 1
            sum = begin + end
            mid = sum // 2 + sum % 2  # 这个地方加上sum%2是为了确保偶数个数时我们求的是中间两个数的后一个
            return sorted(lis)[mid]
        def BFPRT(nums, left, right):
            """分成每5个数一个小组,并求出每个小组内的中位数"""
            num = right - left + 1
            offset = 0 if num % 5 == 0 else 1  # 最后如果剩余的数不足5个,我们也将其分成一个小组,和前面同等对待
            groups = num // 5 + offset
            median = []  # 中位数数组
            for i in range(groups):
                begin = left + i * 5
                end = begin + 4
                Median = getmedian(nums[begin:min(end, right) + 1])
                median.append(Median)
            return getmedian(median)
        def partition(nums, left, right, base):
            """在 nums[left, right] 将基准base归位"""
            temp = nums[base]
            nums[base], nums[right] = nums[right], nums[base]  # 基准和末尾元素互换
            max_index = left
            for i in range(left, right):  # 把所有小于基准的移到左边
                if nums[i] <= temp:  # 要等于啊!这里好坑的说.. 否则通不过[3, 3, 3, 3, 4, 3, 3, 3, 3]  k = 1
                    nums[max_index], nums[i] = nums[i], nums[max_index]
                    max_index += 1
            nums[right], nums[max_index] = nums[max_index], nums[right]  # 基准归位
            return max_index
        def select(nums, left, right, k_smallest):
            """在 nums[left, right] 找第k小的元素"""
            if left == right:  # 递归终止条件
                return nums[left]
            # pivot_index = random.randint(left, right)
            base = BFPRT(nums, left, right)
            base_index = partition(nums, left, right, nums.index(base))  # 选base为基准,并归位。
            if base_index == k_smallest:  # 判断目前已归位的基准,是不是第k_smallest位
                return nums[k_smallest]
            elif k_smallest < base_index:  # 递归左半部分
                return select(nums, left, base_index - 1, k_smallest)
            else:  # 递归右半部分
                return select(nums, base_index + 1, right, k_smallest)
        return select(nums, 0, len(nums) - 1, len(nums)-k)  # 第k大,是第n-k小
【Leetcode Top-K问题 BFPRT】第三大的数(414)的更多相关文章
- [LeetCode] Top K Frequent Elements 前K个高频元素
		Given a non-empty array of integers, return the k most frequent elements. For example,Given [1,1,1,2 ... 
- LeetCode "Top K Frequent Elements"
		A typical solution is heap based - "top K". Complexity is O(nlgk). typedef pair<int, un ... 
- [LeetCode] Top K Frequent Words 前K个高频词
		Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ... 
- Top K问题-BFPRT算法、Parition算法
		BFPRT算法原理 在BFPTR算法中,仅仅是改变了快速排序Partion中的pivot值的选取,在快速排序中,我们始终选择第一个元素或者最后一个元素作为pivot,而在BFPTR算法中,每次选择五分 ... 
- LeetCode - Top K Frequent Words
		Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ... 
- 数组中的第K个最大元素leetcode(Top K的问题)
		在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 ... 
- LeetCode 第三大的数414. Third Maximum Number
		题目 描述:给定数组中求第三大的数字:如果没有,返回最大的:时间复杂度O(n) 记得<剑指offer>才看到过这样的求第k大的题目.但是忘记具体怎么做了.只好先自己想了. 因为时间复杂度的 ... 
- Top K Frequent Elements 前K个高频元素
		Top K Frequent Elements 347. Top K Frequent Elements [LeetCode] Top K Frequent Elements 前K个高频元素 
- LeetCode 414. 第三大的数(Third Maximum Number) 3
		414. 第三大的数 414. Third Maximum Number 题目描述 给定一个非空数组,返回此数组中第三大的数.如果不存在,则返回数组中最大的数.要求算法时间复杂度必须是 O(n). 每 ... 
- C#版(打败99.28%的提交) - Leetcode 347. Top K Frequent Elements - 题解
		版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ... 
随机推荐
- 图解nginx配置负载均衡
			1. 在Linux上准备两份tomcat 2. 修改两份tomcat的端口号 修改的端口如图所示: 3. 启动两个tomcat服务器 4. 修改两个服务器上的主页方便测试区分 5. 在nginx配置文 ... 
- 解决linux机器克隆后eth0不见的问题
			克隆机器之后,两个几的物理地址和ip地址是一样的,导致克隆的机器网络不可用,可以通过通过如下步骤修改: 通过ifconfig –a 命令可查看所有的ip地址配置. 通过这个命令可以发现有一个eth ... 
- 长按触发(PC端和移动端)
			$.fn.longPress = function(fn) { var timeout = undefined; var $this = this; for(var i = 0;i<$this. ... 
- charles for https
			To remotely capture http or https traffic with charles you will need to do the following: HOST - Mac ... 
- Python字符串切片操作知识详解
			Python字符串切片操作知识详解 这篇文章主要介绍了Python中字符串切片操作 的相关资料,需要的朋友可以参考下 一:取字符串中第几个字符 print "Hello"[0] 表 ... 
- mysql大数据表优化
			1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉 ... 
- JS中的一些函数式编程术语
			组合 Composition 组合某种类型(含函数)的两个元素,进而生成一个该类型的新元素: JavaScript 1 2 3 4 5 6 7 let compose = (f ... 
- IDEA中配置国内maven库镜像(阿里云)
			配置maven中settings.xml,在mirrors段内增加镜像配置,配置后如下: <mirror> <id>nexus-aliyun</id> <mi ... 
- 微信网页授权demo2
			1.在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名.请注意,这里填写的是 ... 
- mac 将本地文件上传到vps
			打开mac终端 假设通过ssh连接远程vps命令为. ssh root@194.10.10.23 -p92322 (说明:92322表示端口号,一般vps端口号默认是22) 那么复制本地文件到终端的命 ... 
