【问题标题】:Getting the kth largest elemtent with quick select通过快速选择获得第 k 个最大的元素
【发布时间】:2021-07-23 20:08:03
【问题描述】:

我编写了一些 python 代码来获取未排序数组中的第 K 个最小元素。我想获得帮助来反转函数以获得第 K 个最大元素。我知道 StackOverflow 上还有其他问题可以回答这个问题,但老实说,我不在这里是因为我想回答我的问题。我在这里是因为我想要这种模式,如何思考这些问题,以便下次我看到这样的问题时能够回答。所以请给我解释清楚,帮助我真正明白该怎么做,这样我以后才能做类似的问题。

from typing import List


def partition(array: List[int], lowerbound: int, upperbound: int) -> int:
    """
    Partitions the array so that lower items are to the left of the pivot and bigger items are to the right.
    """
    pivot = array[upperbound]
    index_1 = lowerbound - 1

    for index_2 in range(lowerbound, upperbound):  # we loop from lowerbound and stop just before the pivot.
        if array[index_2] < pivot:  # if the value at index 2 is less than the pivot.
            index_1 += 1
            array[index_1], array[index_2] = array[index_2], array[index_1]  # swap index one and two
    array[index_1 + 1], array[upperbound] = array[upperbound], array[index_1 + 1]
    return index_1 + 1  # return the pivot(basically it's index)


def quick_select(array: List[int], lowerbound: int, upperbound: int, item_index: int) -> int:
    """
    Performs the quick select algorithm.
    """
    if lowerbound >= upperbound:
        return array[lowerbound]

    pivot_index = partition(array, lowerbound, upperbound)
    if pivot_index == item_index:
        return array[item_index]

    if pivot_index > item_index:
        return quick_select(array, lowerbound, pivot_index - 1, item_index)
    else:
        return quick_select(array, pivot_index + 1, upperbound, item_index)
    ```


【问题讨论】:

  • 那么问题是什么?你在哪里卡住了?
  • 问题是在未排序的数组中找到第 k 个最大的元素。 @MrSmith42 正如我上面所说,我的代码找到了第 k 个最小的元素。我只想知道如何反转它以获得最大的元素。
  • 在更改代码之前,您需要了解代码。想出一个简单的测试用例。使用调试器单步执行代码以查看它的作用,或者只需添加一堆 print 语句来显示它的作用。一旦你理解了代码,修改就很容易了。
  • 顺便说一句:您应该发布minimal reproducible example。需要更改的部分不在您显示的代码中。
  • @user3386109 我理解上面的代码。很好。这不是一些复制和粘贴的代码。我只需要知道要在我的代码中更改什么,以便它找到与现在发现的相反的内容。我什至不知道从哪里开始,所以对于最小的可重现示例,我不知道从哪里开始。

标签: python algorithm data-structures quicksort


【解决方案1】:

至少有两种方式:

  • 第 K 个最大的就是第 (N+1-K) 个最小的,你甚至不需要重写算法。

  • 在给定的代码中,只要有元素比较,就翻转其方向(将 > 转为 = 转为 仅元素比较。


另一种选择是更改数组中所有元素的符号,寻找最小的并恢复符号。

我不会推荐这种方法,除非符号的改变是虚拟完成的,即在涉及元素的语句中假设。例如。 a > b 被改写为 -a > -b,也是 a

【讨论】:

  • @Dave:大概你不理解这个简单的规则。我不知道您使用的是什么索引来源,请检查一下。
  • 谢谢。我重新审视了你的逻辑,它有效。
【解决方案2】:

获得第 K 个最大的是相同的代码,你只是以另一种方式索引。

完全未经测试的代码

def KthLargest(array: List[int], item_index: int)
  return quick_select(array, 0, len(List), len(list)-item_index) # off-by-one?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-21
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 2015-10-06
    • 2019-08-13
    • 2021-08-29
    相关资源
    最近更新 更多