【问题标题】:What is the minimum number of swaps required to bubble sort an array?对数组进行冒泡排序所需的最小交换次数是多少?
【发布时间】:2017-01-09 08:25:28
【问题描述】:

我正在尝试解决 Hackerrank 问题New Year Chaos

可以在页面上找到进一步的解释。例如,将“已交换”队列表示为q,如果q = [2, 1, 5, 3, 4],则所需的交换次数为3:

根据https://www.quora.com/How-can-I-efficiently-compute-the-number-of-swaps-required-by-slow-sorting-methods-like-insertion-sort-and-bubble-sort-to-sort-a-given-array的第一个答案,冒泡排序所需的交换次数等于数组的反转次数。我尝试使用以下 Hackerrank 提交来测试这一点:

#!/bin/python

import sys


T = int(raw_input().strip())
for a0 in xrange(T):
    n = int(raw_input().strip())
    q = map(int,raw_input().strip().split(' '))
    # your code goes here
    diff = [x - y for x, y in zip(q, range(1,n+1))]
    if any([abs(el) > 2 for el in diff]):
        print "Too chaotic"
    else:
        all_pairs = [(q[i], q[j]) for i in range(n) for j in range(i+1, n)]
        inversions = [pair[0] > pair[1] for pair in all_pairs]
        print inversions.count(True)

这里也是本地运行的代码版本:

n = 5
q = [2, 1, 5, 3, 4]

diff = [x - y for x, y in zip(q, range(1,n+1))]
if any([abs(el) > 2 for el in diff]):
    print "Too chaotic"
else:
    all_pairs = [(q[i], q[j]) for i in range(n) for j in range(i+1, n)]
    inversion_or_not = [pair[0] > pair[1] for pair in all_pairs]
    print inversion_or_not.count(True)

对于给定的测试用例,脚本正确打印数字 3。但是,对于所有其他“隐藏”测试用例,它给出了错误的答案:

我也尝试过实现冒泡排序的提交:

#!/bin/python

import sys

def swaps_bubble_sort(q):
    q = list(q)         # Make a shallow copy
    swaps = 0
    swapped = True
    while swapped:
        swapped = False
        for i in range(n-1):
            if q[i] > q[i+1]:
                q[i], q[i+1] = q[i+1], q[i]
                swaps += 1
                swapped = True
    return swaps

T = int(raw_input().strip())
for a0 in xrange(T):
    n = int(raw_input().strip())
    q = map(int,raw_input().strip().split(' '))
    # your code goes here
    diff = [x - y for x, y in zip(q, range(1,n+1))]
    if any([abs(el) > 2 for el in diff]):
        print "Too chaotic"
    else:
        print swaps_bubble_sort(q)

但结果相同(失败)。最小交换次数不等于反转次数还是冒泡排序获得的?

【问题讨论】:

  • 请不要将文字作为图片发布。
  • 尝试生成自己的测试用例。

标签: python algorithm sorting


【解决方案1】:

您只需计算冒泡排序中必要交换的次数。这是我被接受的代码。

T = input()
for test in range(T):
    n = input()
    l = map(int, raw_input().split())
    for i,x in enumerate(l):
        if x-(i+1) > 2:
            print "Too chaotic"
            break
    else:
        counter = 0
        while 1:
            flag = True
            for i in range(len(l)-1):
                if l[i] > l[i+1]:
                    l[i],l[i+1] = l[i+1],l[i]
                    counter += 1
                    flag = False
            if flag:
                break
        print counter

在您的第一个代码中,您的方法是O(n^2),它不适用于n = 10^5。在这一行

all_pairs = [(q[i], q[j]) for i in range(n) for j in range(i+1, n)]

您正在尝试在 RAM 中存储 10^10 元组。

您的第二个代码的问题是您使用 diff 元素的abs 来确保数组不混乱。但是,一个人只能通过贿赂才能走到最后,这并不违反规则。所以你只需要确保一个人不会超过两个位置而不是相反。

【讨论】:

    【解决方案2】:

    Swift 4 版本:

    func minimumBribes(queue: [Int]) -> Int? {
    
      for (index, value) in queue.enumerated() {
         if value - (index + 1) > 2 { // `+ 1` needed because index starts from `0`, not from `1`.
            return nil
         }
      }
      var counter = 0
      var queue = queue // Just a mutable copy of input value.
      while true {
         var isSorted = true
         for i in 0 ..< queue.count - 1 {
            if queue[i] > queue[i + 1] {
               queue.swapAt(i, i + 1)
               counter += 1
               isSorted = false
            }
         }
         if isSorted {
            break
         }
      }
      return counter
    }
    
    // Complete the minimumBribes function below.
    func minimumBribes(q: [Int]) -> Void {
    
        if let value = minimumBribes(queue: q) {
            print("\(value)")
        } else {
            print("Too chaotic")
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      干净的python解决方案:

      def minimumBribes(q):
          b = 0
          for i, x in enumerate(q):
              if x - i > 3:
                  print('Too chaotic')
                  return
              for y in q[max(0, x - 2):i]:
                  if y > x:
                      b += 1
          print(b)
      

      【讨论】:

        猜你喜欢
        • 2015-01-06
        • 2016-04-04
        • 1970-01-01
        • 2015-11-01
        • 2012-01-08
        • 2019-08-08
        • 2012-07-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多