对数组进行排序所需的最小交换次数

问题描述 投票:0回答:6

我有一个大小为 n 的数组,其中包含从 1 到 n 的元素,按随机顺序排列。因此,我们有一个无序整数数组作为输入。

考虑到我可以交换任意两个元素任意次数,我怎样才能找到这种交换的最小次数以使数组排序?

arrays sorting swap
6个回答
0
投票

这可以在 O(n) 内完成。假设元素在 1 到 n 范围内并且没有重复项。

noofswaps = 0
for i in range(len(A)):
    while A[i] != i + 1:
        temp = A[i]
        A[i] = A[A[i] - 1]
        A[temp - 1] = temp
        noofswaps += 1
print noofswaps

0
投票
static int minimumSwaps(int[] arr) {
        int swap=0;
        boolean newarr[]=new boolean[arr.length];

        for(int i=0;i<arr.length;i++){
            int j=i,count=0;

            while(!newarr[j]){
                newarr[j]=true;
                j=arr[j]-1;
                count++;
            }

            if(count!=0)
                swap+=count-1;
        }
        return swap;
}

0
投票

我将尝试使用 JavaScript 来回答这个问题。 这是迄今为止我尝试过的最佳代码:

function minimumSwaps(arr) {
    var arrLength = arr.length;

    // create two new Arrays 
    // one record value and key separately
    // second to keep visited node count (default set false to all)

    var newArr = [];
    var newArrVisited = [];
    for (let i = 0; i < arrLength; i++) {
        newArr[i]= [];
        newArr[i].value = arr[i];
        newArr[i].key = i;
        newArrVisited[i] = false;
    }

    // sort new array by value

    newArr.sort(function (a, b) {
        return a.value - b.value;
    })

    var swp = 0;
    for (let i = 0; i < arrLength; i++) {

        // check if already visited or swapped
        if (newArr[i].key == i || newArrVisited[i]) {
            continue;
        }

        var cycle = 0;
        var j = i;
        while (!newArrVisited[j]) {

            // mark as visited
            newArrVisited[j] = true;
            j = newArr[j].key; //assign next key
            cycle++;
        }
        if (cycle > 0) {
            swp += (cycle > 1) ? cycle - 1 : cycle;
        } 

    }
    return swp;
}

参考-1

参考-2


0
投票

使用哈希图实现最小交换 2 的 Hackerrank Python 代码

length = int(input())
arr= list(map(int,input().split()))
hashmap = {}

for i in range(0,len(arr)):
    hashmap[i+1] = [arr[i],False]

swap_count = 0
for e_pos, e_val in hashmap.items():
    if e_val[1] == False:
        e_val[1] = True
        if e_pos == e_val[0]:
            continue
        else:
            c = e_val[0]
            while hashmap[c][1] == False:
                hashmap[c][1] = True
                b = hashmap[c][0]
                c = b
                swap_count+=1
print(swap_count)

0
投票

GeeksForGeeks

有一个有趣的看法
  • 时间复杂度:O(N),其中 N 是数组的大小。
  • 辅助空间:O(1)

使用的方法是

  1. 对于arr[]中的每个索引,检查当前元素是否位于正确的位置。由于数组包含从 1 到 N 的不同元素,我们可以简单地将元素与其在数组中的索引进行比较,以检查它是否位于正确的位置。
  2. 如果当前元素不在正确的位置,则将该元素与已占据其位置的元素交换(使用临时变量)
  3. 否则检查下一个索引 (i += 1)

这是代码

def minimumSwaps(arr):
    min_num_swaps = 0; 
    i = 0; 
    while (i < len(arr)):  
        if (arr[i] != i + 1): 
            while (arr[i] != i + 1): 
                temp = 0; 
                temp = arr[arr[i] - 1]; 
                arr[arr[i] - 1] = arr[i]; 
                arr[i] = temp; 
                min_num_swaps += 1; 

        i += 1; 
      
    return min_num_swaps;

可以轻松更新为

  • 删除分号

  • 消除对临时的需要

  • 用给定的整数输入 n 和数组的大小替换 len(arr)

    def minimumSwaps(arr):
        min_num_swaps = 0
        i = 0
        while (i < n-1):  
            if (arr[i] != i + 1): 
                while (arr[i] != i + 1): 
                    arr[arr[i] - 1], arr[i] = arr[i], arr[arr[i] - 1]
                    min_num_swaps += 1
    
            i += 1; 
    
         return min_num_swaps
    

他们都将通过 HackerRank

中当前所有 15 个测试用例


0
投票

这是我使用java 7的minimumsawap函数的代码

static int minimumSwaps(int[] arr) {
        int c=0;
        for(int i=0;i<arr.length;i++){
            if(arr[i]!=(i+1)){
                int t= arr[i];
                arr[i]=arr[t-1];
                arr[t-1]=t;
                c++;
                i=0;
            }
        }
        return c;
    }
© www.soinside.com 2019 - 2024. All rights reserved.