Python-从有序数组中寻找第K大值以及类似题--字节算法题

这篇博客介绍了如何在无序数组中找到第K个最大元素,以及如何在两个正序数组中找到中位数。针对第一题,通过修改快速排序实现找到第K大元素;第二题,通过合并两个正序数组并返回中位数;第三题,合并两个有序数组找到第K大数。这些方法都涉及排序和查找算法的应用。
摘要由CSDN通过智能技术生成

题目一:LT215-无序数组的第K个元素

题目:在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

首先需要做的是找一个方法做排序,让arr有序。
可以用快速排序来做,排完了之后的第L-k+1个数
首先回忆快速排序的方法
快速排序的算法首先是partition 函数 找中间区间的位置。

def partition(arr,low,high):
	pivot = arr[high]
	i = low -1 
	for j in range(low,high):
		if arr[j] <= pivot: 
			i += 1 
			arr[i],arr[j] = arr[j],arr[i]
	arr[i+1],arr[high] = arr[high],arr[i+1]
	return i+1
def quickSort(arr,low,high):
	if low < high:
		mid = partition(arr,low,high)
		quickSort(arr, low,mid-1)
		quickSort(arr,mid+1,high)

这里想想,partition函数是为了找中间位置的mid,然后arr[mid]左边的mid-1个数 都是比arr[mid]小;右边的总长度 - mid 个数 都是比 arr[mid] 大。
那么我们要找 第K个最大的数。 可以把quickSort 改一下就可以找到我们的要找的第K个大的数。
首先第K大个数,因为排序后是从小到大的,所以这个位置上 右边是K-1个数 比这个数大就行。

class Solution:
    def partition(self,arr,low,high):
        pivot = arr[high]
        i = low -1 
        for j in range(low,high):
            if arr[j] <= pivot: 
                i += 1 
                arr[i],arr[j] = arr[j],arr[i]
        arr[i+1],arr[high] = arr[high],arr[i+1]
        return i+1
    def topK(self,arr,low,high,k):
        L = len(arr)-1
        if low < high:
            mid = self.partition(arr,low,high)
            #arr[mid] 左边的mid个都比arr[mid]小
            #arr[mid] 右边的L-mid都比 arr[mid]大 
            if L-mid == k-1: return 
            elif L-mid > k-1: self.topK(arr,mid+1,high,k)
            else: self.topK(arr,low,mid-1,k)  
    def findKthLargest(self, nums: List[int], k: int) -> int:
        self.topK(nums,0,len(nums)-1,k)
        return nums[-k]

题目二:LT4-寻找两个正序数组的中位数

题目:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
输入:nums1 = [], nums2 = [1]
输出:1.00000

思路是:先使用并归排序,合并后就可以直接返回中位数。

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        p,q = 0,0
        ans = []
        while p < len(nums1) and q < len(nums2):
            if nums1[p] < nums2[q]:
                ans.append(nums1[p])
                p+=1 
            else:
                ans.append(nums2[q])
                q+=1 
        ans+= nums1[p:]
        ans+= nums2[q:]
        L = len(ans)
        if L%2==1:
            return float(ans[L//2])
        else:
            return float((ans[L//2]+ans[L//2 -1 ])/2)

所以同时可以合并之后,返回第K的元素。

题目三:面试题-合并两个有序数组,返回第K大的数

已知有两个从小到大的有序数组,求两个数组的第k大的数

这是字节跳动的面试题。如果当时有系统性刷过题,可能这道题就做出来了。

def topK(nums1,nums2,k):
	p,q=0,0
	ans = []
	while p < len(nums1) and q < len(nums2):
		if nums1[p] < nums2[q]:
			ans.append(nums1[p])
			p+=1 
		else:
			ans.append(nums2[q])
			q+=1
	return ans[-k]
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jianafeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值