如何找到对列表进行排序的最小移动次数?

时间:2019-08-25 12:31:34

标签: python python-3.x sorting

在N个不同整数的给定列表A中,我想通过将元素以升序移动到列表末尾来找到对列表进行排序所需的最小移动次数。

  

输出为:1 4 3 2 5 [1、3、2、5、4] 1 [1、2、5、4、3] 2 [1、2、4、3,   5] 3 [1、2、3、5、4] 4 [1、2、3、4、5] 5无

def end_sort(a,c):
    for i in range(len(a)):
        if(a[i]>a[i+1]):
            a.append(a.pop(i))
            c+=1 
            print(a,c)
            break
    if(a!=sorted(a)):
        end_sort(a,c)
    else:
        return c 
a=list(map(int,input().split(" ")))
c=0
co=end_sort(a,c)
print(co,end="") 

1 个答案:

答案 0 :(得分:1)

让我们首先观察以下事实。

  1. 要获得最少的步数,一个数字只能移动一次;
  2. 必须先移动较小的数字才能在左侧结束;
  3. 如果数字右边有一个较小的数字,则该数字不合适。

考虑到这一点,我们可以从右向左遍历列表,并跟踪不递减的(3)的数字。通过对这些数字(2)进行排序,我们可以获得最佳步骤。这是最佳选择,因为必须移动的数字仅移动一次(1)

def end_sort_steps(lst):
    steps = []
    right_min = max(lst)

    for n in reversed(lst):
        if n >= right_min:
            # Then the number must be moved
            steps.append(n)
        else:
            # Otherwise it is the smallest number seen yet
            right_min = n

    return sorted(steps)

print(end_sort_steps([1, 4, 3, 2, 5])) # [3, 4, 5]
# This corresponds to the steps:
# [1, 4, 3, 2, 5] -> [1, 4, 2, 5, 3] -> [1, 2, 5, 3, 4] -> [1, 2, 3, 4, 5]

根据您对该算法的使用情况,剩下的就是将输出结果转换为可用的格式,以表示您的步骤顺序。

或者,只要这很重要,您就可以简单地保留步数。

def end_sort_steps(lst):
    steps = 0
    right_min = max(lst)

    for n in reversed(lst):
        if n >= right_min:
            # Then the number must be moved
            steps += 1
        else:
            # Otherwise it is the smallest number seen yet
            right_min = n

    return steps