【发布时间】:2017-12-20 03:28:44
【问题描述】:
假设给定一个整数数组。所有相邻的元素都保证是不同的。让我们使用以下关系将这个数组 a 的 bitonicity 定义为 bt:
bt_array[i] = 0, if i == 0;
= bt_array[i-1] + 1, if a[i] > a[i-1]
= bt_array[i-1] - 1, if a[i] < a[i-1]
= bt_array[i-1], if a[i] == a[i-1]
bt = last item in bt_array
我们说一个数组的双调性是最小,当它的双调性为0时,如果它有奇数个元素,或者它的双调性是+1或-1,如果它有偶数个元素.
问题是要设计一种算法来找到最少的交换次数,以使任何数组的双调性最小。该算法的时间复杂度最差应该是 O(n),n 是数组中元素的数量。
例如,假设a = {34,8,10,3,2,80,30,33,1}
它的初始bt 是-2。最小值为 0。这可以通过 1 次交换来实现,即交换 2 和 3。所以输出应该是 1。
这里有一些测试用例:
测试用例 1:a = {34,8,10,3,2,80,30,33,1},最小交换次数 = 1(交换 2 和 3)
测试用例 2:{1,2,3,4,5,6,7}:min swaps = 2(将 7 与 4 交换,将 6 与 5 交换)
测试用例 3:{10,3,15,7,9,11}:min swaps = 0。bt = 1。
还有一些:
{2,5,7,9,5,7,1}:当前
bt= 2。交换 5 和 7:minSwaps = 1{1,7,8,9,10,13,11}:当前
bt= 4:交换 1,8:minSwaps = 1{13,12,11,10,9,8,7,6,5,4,3,2,1}:当前
bt= -12:交换 (1,6),(2,5 ) 和 (3,4) : minSwaps = 3
我在一次采访中被问到这个问题,这是我想出的:
1. Sort the given array.
2. Reverse the array from n/2 to n-1.
3. Compare from the original array how many elements changed their position.
Return half of it.
还有我的一些代码:
int returnMinSwaps(int[] a){
int[] a = {1,2,3,4,5,6,7};
int[] b = a;
Arrays.sort(b);
for(int i=0; i<= b.length/2 - 1; i++){
swap(b[b.length - i], b[b.length/2 - i]);
}
int minSwaps = 0;
for(int i=0;i<b.length;i++){
if(a[i] != b[i])
minSwaps++;
}
return minSwaps/2;
}
不幸的是,对于使用此逻辑的某些测试用例,我没有得到正确的最小方法数。另外,我正在对O(n log n) 中的数组进行排序,并且需要在O(n) 中完成。
【问题讨论】:
-
@VidorVistrom:所有元素都是不同的。但在我看来,我想你想问两个相邻的元素是否不同,对吧?所有相邻的元素都是不同的。让我也将其放入编辑中。感谢您指出。
-
@YakymPirozhenko 交替排列只是双调数组的一种特殊情况。它可以是
{+, -, +, -, ...},也可以是{+, -, -, -, +, -, +, +}。这两种情况都具有此问题中定义的“最小双调性”。 -
@CodeHunter 哦,我明白了。所以整个数组并不明显。那么,在交换导致相邻元素相同的情况下,如何计算结果数组的双调性?你对
a[i] == a[i - 1]时会发生什么没有条件。 -
交换之后。例如
a={1, 3, 4, 1}。根据您的规则,这是有效的。我们将 3 与最后的 1 交换。然后我们需要计算双调性,但这不再可能。 -
好的。请注意,使用此规则,您不再需要保证初始数组中的相邻元素是不同的。现在它们可以相同了,这彻底改变了问题。