【问题标题】:Minimum number of swaps needed to sort the array对数组进行排序所需的最小交换次数
【发布时间】:2015-01-06 02:51:07
【问题描述】:

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

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

【问题讨论】:

标签: arrays sorting swap


【解决方案1】:

这可以在 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

【讨论】:

  • 在 { 1, 3, 5, 2, 4, 6, 8 } 的情况下,您将使用此代码获得超出范围的异常。您需要在 while 循环中进行额外检查: A[i]
  • 输入 { 1, 3, 5, 2, 4, 6, 8 } 不是有效示例。输入列表限制元素必须在 1 到 n 范围内且不能重复。
  • 元素顺序随机,可能有重复的情况怎么办?
【解决方案2】:
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;
}

【讨论】:

    【解决方案3】:

    我将尝试使用 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;
    }
    

    reference -1

    reference -2

    【讨论】:

      【解决方案4】:

      Hackerrank Python 代码使用 hashmaps 进行最小交换 2

      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)
      

      【讨论】:

        【解决方案5】:

        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个测试用例

        【讨论】:

          猜你喜欢
          • 2019-08-08
          • 2017-01-09
          • 1970-01-01
          • 2013-02-15
          • 2015-02-18
          • 2018-07-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多