Python 如何实现仅执行;K";时代

Python 如何实现仅执行;K";时代,python,algorithm,Python,Algorithm,我正在解决下面的冒泡排序算法 然而,该算法似乎不是常见的冒泡排序实现。我已经实现了以下代码,但它将超时。原因是我的代码的时间复杂度仍然是O(n^2) 如何为冒泡排序编写代码以正确理解和解决问题 解决方案 气泡排序是一种算法,它对长度为N的序列进行排序,检查两个相邻元素以改变其位置。气泡排序可以执行N次,如下所示 比较第一个值和第二个值,如果第一个值更大,则更改位置 比较第二个值和第三个值,如果第二个值更大,则更改位置 比较N-1和N-th值,如果N-1th值更大,则更改位置。 我知道气泡排

我正在解决下面的冒泡排序算法

然而,该算法似乎不是常见的冒泡排序实现。我已经实现了以下代码,但它将超时。原因是我的代码的时间复杂度仍然是O(n^2)

如何为冒泡排序编写代码以正确理解和解决问题

解决方案

气泡排序是一种算法,它对长度为N的序列进行排序,检查两个相邻元素以改变其位置。气泡排序可以执行N次,如下所示

  • 比较第一个值和第二个值,如果第一个值更大,则更改位置

  • 比较第二个值和第三个值,如果第二个值更大,则更改位置

  • 比较N-1和N-th值,如果N-1th值更大,则更改位置。 我知道气泡排序的结果,所以我知道气泡排序的中间过程。然而,由于N非常大,执行上述步骤K次需要很长时间。编写一个程序,帮助您找到气泡排序的中间过程
  • 输入

    N和K在第一行中给出

    第二行给出第一个序列的状态。也就是说,形成第一个序列的N个整数依次给出,它们之间有空格


    1我不明白你为什么说“原因是我的代码的时间复杂度仍然是O(n^2)”


    时间复杂度始终为O(n²),除非您添加一个标志来检查列表是否已排序(如果在程序开始时对列表进行排序,则复杂度现在将为0(n)

    我不明白您为什么说“原因是我的代码的时间复杂度仍然是O(n^2)”


    时间复杂度始终为O(n²),除非您添加一个标志来检查列表是否已排序(如果列表在程序开始时排序,则复杂度现在将为0(n)

    据我所知,您已经实现了请求的算法。它是O(nk)
    Phillippe
    已经介绍了我输入的基本原理

    是的,您可以设置一个标志来指示您是否在此通行证上进行了任何交换。除了最佳情况,这不会改变任何复杂性——尽管在许多其他情况下,它确实降低了常数因子

    我认为加快进程的一种可能性是使用更有效的值交换:使用Python惯用语
    a,b=b,a
    。在您的情况下,内部循环可能会变成:

    done = True
    for j in range(i, n_k_s[0]-1):
        if progressions[j] > progressions[j+1]:
            progressions[j], progressions[j+1] = progressions[j+1], progressions[j]
            done = False
    if done:
        break
    

    据我所知,您已经实现了所要求的算法。它是O(nk)
    Phillippe
    已经介绍了我输入的基本原理

    是的,您可以设置一个标志来指示您是否在此通行证上进行了任何交换。除了最佳情况,这不会改变任何复杂性——尽管在许多其他情况下,它确实降低了常数因子

    我认为加快进程的一种可能性是使用更有效的值交换:使用Python惯用语
    a,b=b,a
    。在您的情况下,内部循环可能会变成:

    done = True
    for j in range(i, n_k_s[0]-1):
        if progressions[j] > progressions[j+1]:
            progressions[j], progressions[j+1] = progressions[j+1], progressions[j]
            done = False
    if done:
        break
    

    当在示例输入中键入“4和1”时,列表将被排序一次。在这种情况下,我认为它是O(n)。但是,当值为“4和2”或更大时,需要O(n^2)的时间复杂度。如果是这样,如果我每次执行排序时创建并返回一个有序列表,我是否可以保持O(n)?这就是我们想要的问题吗?当你把K设为1时,你的时间复杂度实际上是O(n)。当你把K设为2时,你的时间复杂度变成O(n*2),因此,你的算法的时间复杂度是O(n*K)。如果每次都创建一个新列表,算法的复杂度不会改变,因为您仍然会执行列表K次。如果时间复杂度超过O(n^2),此问题将导致超时错误。所以我认为问题在于你不想实现简单的冒泡排序。您对此有何看法?在您的回答中,我想我得到了一个提示。@COLEAN(很抱歉回答得太晚)如果您想使用复杂度低于O(n^2)的冒泡排序,您需要在其中实现退出条件。IE:您可以添加一个标志,每当您循环时,检查您是否实际交换了元素。如果您没有,这意味着您的列表已排序。例如:15 32 23 62,K=5=>第一次排序时,您将得到15 23 32 62(32次交换,23)=>第二次排序时,您不必交换任何内容,因为列表已排序,因此您应该退出代码=>时间复杂度变为O(n*2),本应为O(n*5)。在示例输入中键入“4和1”时,列表只排序一次。在这种情况下,我认为它是O(n)。但是,当值为“4和2”或更大时,需要O(n^2)的时间复杂度。如果是这样,如果我每次执行排序时创建并返回一个有序列表,我是否可以保持O(n)?这就是我们想要的问题吗?当你把K设为1时,你的时间复杂度实际上是O(n)。当你把K设为2时,你的时间复杂度变成O(n*2),因此,你的算法的时间复杂度是O(n*K)。如果每次都创建一个新列表,算法的复杂度不会改变,因为您仍然会执行列表K次。如果时间复杂度超过O(n^2),此问题将导致超时错误。所以我认为问题在于你不想实现简单的冒泡排序。您对此有何看法?在您的回答中,我想我得到了一个提示。@COLEAN(很抱歉回答得太晚)如果您想使用复杂度低于O(n^2)的冒泡排序,您需要在其中实现退出条件。IE:您可以添加一个标志,每当您循环时,检查您是否实际交换了元素。如果您没有,这意味着您的列表已排序。例:15 32 23 62,K=5=>第一次排序时,将得到15 2
    done = True
    for j in range(i, n_k_s[0]-1):
        if progressions[j] > progressions[j+1]:
            progressions[j], progressions[j+1] = progressions[j+1], progressions[j]
            done = False
    if done:
        break