day2:215. 数组中的第K个最大元素 快速排序 python代码


"""
快速排序
思想: 
基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,
其中一部分的所有数据都比另外一部分的所有数据都要小,
然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,
以此达到整个数据变成有序序列。

"""

# 方法1: 递归
def partition(arr, first, end):
    i, j = first, end
    while i < j:
        while i < j and arr[i] <= arr[j]:
            j = j - 1
        if i < j:
            # 交换
            temp = arr[j]
            arr[j] = arr[i]
            arr[i] = temp
            i = i + 1

        while i < j and arr[i] <= arr[j]:
            i = i + 1
        if i < j:
            # 交换
            temp = arr[j]
            arr[j] = arr[i]
            arr[i] = temp
            j = j - 1
            
    return i


# 数据发生了变化; 不用返回
def quicksort(arr, low, heigh):
    # print(arr)
    if low < heigh:
        i = partition(arr, low, heigh)
        quicksort(arr, low, i-1)
        quicksort(arr, i+1, heigh)


# 快速排序 不用设定 返回值;
arr = [10, 7, 8, 9, 1, 5]
n = len(arr)

print("0:")
print(arr)
quicksort(arr, 0, n-1)
print(arr)

print("1:")
value = [23, 13, 49, 6, 31, 19, 28]
print(value)
quicksort(value, 0, len(value) - 1)
print(value)

215. 数组中的第K个最大元素

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

示例 1:

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

示例 2:

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

解法1:

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        nums = sorted(nums)
        return nums[-k]

解法2:

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        
        # 使用快速排序算法
        quicksort(nums, 0, len(nums)-1)
        return nums[-k]

4. 寻找两个正序数组的中位数

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。

请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]
 
则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]
 
则中位数是 (2 + 3)/2 = 2.5

方法1:

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        # 中位数 ; 中间的数, 个数为奇数: 中间的数, 为偶数: 中间两个相加/2
        # 理解 记住  
        # 寻找 第k小(第k大)元素问题 的解法
        def findKthElement(arr1, arr2, k):
            len1, len2 = len(arr1), len(arr2)
            if len1 > len2:  # 第一参数 数组长度长
                return findKthElement(arr2, arr1, k)
            if not arr1:  # arr1 为null
                return arr2[k-1]   # 第k个即为目标
            if k == 1:
                return min(arr1[0], arr2[0])
            # k值减小 , 去掉 前k/2个元素
            i, j = min(k//2, len1)-1, min(k//2, len2)-1
            if arr1[i] > arr2[j]:
                # 说明第k小元素 不再arr[:j]中, k 值发生变化
                return findKthElement(arr1, arr2[j+1:], k-j-1)
            else:
                return findKthElement(arr1[i+1:], arr2, k-i-1)
 
        l1, l2 = len(nums1), len(nums2)
        # 寻找中位数,相当于 寻找 两个 第 k 小问题 【】
        # 若为 偶数: 寻找 两个不同位置 (4+4+1)//2 = 4, (4+4+2)//2=5;
        # 若为 奇数: 寻找 两个相同位置 (4+3+1)//2=4, (4+3+2)// 2=4;
        left, right = (l1+l2+1) // 2, (l1+l2+2) // 2
        return (findKthElement(nums1, nums2, left) + findKthElement(nums1, nums2, right)) / 2
 

寻找两个正序数组中第k小 数值:

# 寻找 第k小元素问题 的解法
def findKthElement(arr1, arr2, k):
    len1, len2 = len(arr1), len(arr2)
    if len1 > len2:  # 第一参数  数组短的放前面
        return findKthElement(arr2, arr1, k)
    if not arr1:  # arr1 为null
        return arr2[k - 1]  # 第k个即为目标
    if k == 1:
        return min(arr1[0], arr2[0])
    # k值减小 , 去掉 前k/2个元素
    i, j = min(k // 2, len1) - 1, min(k // 2, len2) - 1
    if arr1[i] > arr2[j]:
        # 说明第k小元素 不再arr[:j]中, k 值发生变化
        return findKthElement(arr1, arr2[j + 1:], k - j - 1)
    else:
        return findKthElement(arr1[i + 1:], arr2, k - i - 1)

寻找两个正序数组中第k大数值:

这个可以利用求第k小 的算法, 求 第 n大, 相当与 求 ( 两个数组长度之和 - n + 1)小元素;

big = 5 # 第三大 即第 all_len - big + 1 小
a = [3, 4, 5, 6, 6]
b = [10, 34, 35, 36, 37, 38]
find_value = findKthElement(a, b, (len(a)+len(b)) - big + 1)
print(find_value) # 34

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值