问题来自:https://www.geeksforgeeks.org/minimum-number-swaps-required-sort-array/
我将在下面重复: 给定n个不同元素的数组,找到对数组进行排序所需的最小交换次数。
示例:
输入:{4,3,2,1} 输出:2 说明:将索引0与3交换,1与2交换 形成排序数组{1,2,3,4}。
输入:{1,5,4,3,2} 输出:2
我通过以下方式解决了这个问题。
总时间复杂度应为:O(n +(n log n))= O(n log(n))
以下是我为此编写的代码,它适用于所提供的测试用例。
def solution(array)
sorted = array.sort
puts array.inspect
puts sorted.inspect
counter_parts_that_have_been_seen = {}
number_of_swaps_required = 0
array.each_with_index do | val, idx |
if counter_parts_that_have_been_seen[val] == true
next
end
array_val = val
sorted_val = sorted[idx]
if array_val != sorted_val
puts "A swap will be required: array val is #{array_val} and sorted_array_val is #{sorted_val}"
number_of_swaps_required += 1
counter_parts_that_have_been_seen[sorted_val] = true
end
end
puts "Number of swaps required are: #{number_of_swaps_required}"
end
现在,我的问题是,如何验证正确性?我没有天气感,这种方法是正确的。
有人可以对此有所了解吗?
答案 0 :(得分:0)
从未排序数组中的第一个元素开始,检查它是否在正确的位置,如果没有将正确的值交换到该位置。测试可以通过与集合的排序版本进行比较来完成,也可以将所选元素与其后面的每个元素进行比较。
随着你的进展,你可能会遇到处于正确位置的元素 - 要么是因为它们在正确的位置开始,要么在放置一个早期元素时交换它们(最后一个元素必须在所有其他元素被放置的时候)放置)。只需将它们留在原地并转移到下一个元素。
使用此方法,每个交换都会正确放置至少一个元素,某些交换将正确放置两个元素。
正确位置的元素可以从问题中打折扣 - 从来没有必要将其从正确的位置移动以对任何其他元素进行排序。 另外一对元素(例如{3,2,1}中的3和1)永远不需要与任何其他元素交换。它们形成了自己独立的元素。
如果你有一个方法,如上所述,为了获得正确的答案,它显然可以用来评估任何替代方法。
答案 1 :(得分:0)
Index : 0 1 2 3 4 5 6 7 8 9
------+-----+---+---+---+---+---+---+---+---+--
Array : 1 22 32 42 12 83 64 93 73 53
------+-----+---+---+---+---+---+---+---+---+--
A BBBBBBBBBBBBBB CC DD CCCCCCCCCC
Target: 0 2 3 4 1 8 6 9 7 5
Diffs : 0 1 1 1 -3 3 0 2 -1 -4
Source: 0 4 1 2 3 9 6 8 5 7
在此示例中,需要对数组[]进行排序。
您可以看到四个(循环)组:
1
{22,32,42,12}
{83,93,73,53}
64
具有1个成员的组已经排序:需要零交换。 具有4个成员的组可以按每个4个交换进行排序。 (最终交换将两个元素放到最后的位置) 因此,所需的掉期数量为 0 + 3 + 3 + 0
现在你只需要证明你可以在N-1掉期中对N周期进行排序......
答案 2 :(得分:0)
如果有一个元素不在正确的位置,那么一定还有另一个元素不在它的正确位置(第一个元素需要放在被另一个元素占据的其他位置) .如果这以图形的形式表示,则没有正确元素的位置将有一条边朝向它,一条边则从它开始。这将最终形成一个或多个循环。现在,循环中元素的位置都在该循环内。因此,我们现在需要证明如果循环中有“n”个元素,则需要最少的“n-1”次交换来对它们进行排序。 我们可以证明这是归纳法。
基数:n=1
只有一个元素,所以已经排序(微不足道)。这意味着 0 次交换,即 n-1 => 1-1 = 0
假设一个循环中有 k 个元素,则需要最少 k-1 次交换
k+1 个元素
循环中的元素具有朝向它需要的位置的边缘。这个位置有另一个朝向其他位置的边缘。现在,如果我们交换前一个元素,我们将删除前一个边缘,后一个元素进入交换位置。现在我们剩下一个大小为 (k+1)-1 = k 的循环。通过归纳,k 个周期需要 k-1 次交换。因此,k+1 将需要 (k-1)+1 = k 次交换。