以下代码通过合并排序计算数组nums
(成对i,j
,使j>i && nums[i] > nums[j]
)的反转。
是否可以使用相同的方法来计算j>i && nums[i] > 2*nums[j]
等特殊反转的数量?
我应该如何修改此代码?
public static void main (String args[])
{
int[] nums = {9, 16, 1, 2, 3, 4, 5, 6};
System.out.println("Strong Inversions: " + countInv(nums));
}
public static int countInv(int nums[])
{
int mid = nums.length/2;
int countL, countR, countMerge;
if(nums.length <= 1)
{
return 0;
}
int left[] = new int[mid];
int right[] = new int[nums.length - mid];
for(int i = 0; i < mid; i++)
{
left[i] = nums[i];
}
for(int i = 0; i < nums.length - mid; i++)
{
right[i] = nums[mid+i];
}
countL = countInv (left);
countR = countInv (right);
int mergedResult[] = new int[nums.length];
countMerge = mergeCount (left, right, mergedResult);
for(int i = 0; i < nums.length; i++)
{
nums[i] = mergedResult[i];
}
return (countL + countR + countMerge);
}
public static int mergeCount (int left[], int right[], int merged[])
{
int a = 0, b = 0, counter = 0, index=0;
while ( ( a < left.length) && (b < right.length) )
{
if(left[a] <= right[b])
{
merged [index] = left[a++];
}
else
{
merged [index] = right[b++];
counter += left.length - a;
}
index++;
}
if(a == left.length)
{
for (int i = b; i < right.length; i++)
{
merged [index++] = right[i];
}
}
else
{
for (int i = a; i < left.length; i++)
{
merged [index++] = left[i];
}
}
return counter;
}
我试过这个
while ((a < left.length) && (b < right.length)) {
if (left[a] <= right[b]) {
merged[index] = left[a++];
} else {
if (left[a] > 2 * right[b]) {
counter += left.length - a;
}
merged[index] = right[b++];
}
index++;
}
但是while循环中有一个错误,left[a]<2*right[b]
但是left[a+n] maybe>2*right[b]
,例如左数组是{9,16}
而右数组是{5,6}
, 9&lt; 2 * 5 但 16> 2 * 5 。我的代码只是跳过这样的情况,结果数量应该小于它应该
答案 0 :(得分:2)
while
中的mergeCount
循环有两个功能:将left
和right
合并到merged
,并计算left
的数量 - right
倒置。对于特殊的反转,最简单的方法是将循环分成两部分,首先计算反转然后合并。计数反转的新触发器为left[a] > 2*right[b]
。
有两个循环的原因是计算特殊反转需要将left
与2*right
合并,并且排序需要将left
与right
合并。可能在单个循环中使用三个不同的索引,但逻辑会更复杂。
答案 1 :(得分:0)
while ( ( a < left.length) && (b < right.length) ) {
if(left[a] <= right[b]) {
merged [index] = left[a++];
} else {
counter += updateCounter(right[b],a,left);
merged [index] = right[b++];
}
index++;
//Rest of the while loop
}
//Rest of the mergeCount function
}
public static int updateCounter(int toSwitch, int index, int[] array) {
while(index < array.length) {
if(array[index] >= 2*toSwitch)
break;
index++;
}
return array.length-index;
}
效率不高,但应该做好。您使用index
初始化a
,因为低于a
的元素永远不会满足条件。