Input : {4, 3, 2, 1}
Output : 2
Explanation : 交换2、3;4、1即得到 {1, 2, 3, 4}.
Input : {1, 5, 4, 3, 2}
Output : 2
原理上可以转化成图:
{4, 3, 2, 1}的图交换示例
{4, 5, 2, 1, 5}的图交换示例,有两个环
一个环的节点数为K的话,那么环内节点交换到正确位置的次数为K-1次。
所以,数据排序的最少交换次数为:所有环的节点数减1的总和,即数组个数减去环的个数。
注意:这里的环不一定是2元环(如上图中的{3、5}),可能是三元环(如上图中的{2、4、1})、4元环、……、N元环。当数组够大时,如何找出多元环也是个问题。
代码参考:
import os,sys,pdb
def min_swaps(arr):
#算法是正确的
mp = {}
sort_arr = sorted(arr)
for i in range(len(sort_arr)):
mp[sort_arr[i]] = i
# 循环节个数
nCircles = 0
flags = [] # 该位置的数是否被访问过
for i in range(len(arr)):
flags.append(False)
for i in range(len(arr)):
if not flags[i]:
j = i
#下面的循环确实能够找到环
while not flags[j]:
flags[j] = True
# j是当前值应在的正确位置
j = mp[arr[j]]
# print(flags,j)
nCircles += 1
return len(arr) - nCircles
# arr=[0,1,2,3,4,5]
# arr=[0,3,2,1,4,5]
# arr=[1,3,2,4,0,5]
arr=[1,3,5,4,0,2]
print(arr)
nswp=min_swaps(arr)
print(nswp)
国外国内有些答案的结果都是不对的。
这些代码对不对,到时候有空再测试一下。
2020.3.12
初步判断上面的算法是对。