【发布时间】:2016-12-13 05:44:27
【问题描述】:
我想找出二维数组中可能的反转次数。我已经编写了这个程序,需要一些方法来加速它:
import java.io.*;
import java.util.*;
class Solution
{
static long merge(int[] array, int[] left, int[] right)
{
int i = 0, j = 0, count = 0;
while (i < left.length || j < right.length)
{
if (i == left.length)
{
array[i+j] = right[j];
j++;
}
else if (j == right.length)
{
array[i+j] = left[i];
i++;
}
else if (left[i] <= right[j])
{
array[i+j] = left[i];
i++;
}
else
{
array[i+j] = right[j];
count += left.length-i;
j++;
}
}
return count;
}
static long invCount(int[] array)
{
if (array.length < 2)
return 0;
int m = (array.length + 1) / 2;
int left[] = Arrays.copyOfRange(array, 0, m);
int right[] = Arrays.copyOfRange(array, m, array.length);
return invCount(left) + invCount(right) + merge(array, left, right);
}
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
long inversions=0;
int[][] arr2=new int[n][n];
if(n<0)
{
System.out.println("0");
return;
}
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
{
arr2[i][j]=sc.nextInt();
//arr2[i][j]=arr[i][j];
}
long inv=0;
int counter=0;
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
while(counter<n)
{
for(int z=counter;z<n;z++)
{
//System.out.println("comparing "+arr2[i][counter]+" with "+arr2[j][z]);
if(arr2[i][counter]>arr2[j][z])
inv++;
}
counter++;
//System.out.println("end while---------\n");
}
//System.out.println("Row change#########\n");
counter=0;
}
}
for (int i=0;i<n;i++)
inv=inv+invCount(arr2[i]);
System.out.println(inv);
}
}
这个程序可以优化吗?还是这个程序在某个地方出错了? 我得到了 2 个测试用例的正确输出,它们是:2D 数组的 4 次反转:
9 7
1 2
二维数组的 19 次反转:
9 7 6
1 2 5
2 3 1
感谢您的帮助。:)
【问题讨论】:
-
没有理解问题,但我认为将你的代码包装成四个循环是基本问题,因为你在外部代码中得到了大约 n^4 的复杂度,加上(必要的)复杂度 n !为反转。尝试减少外部循环。
-
是的,问题确实是循环,这就是为什么我要求提出一些更好的方法,因为我找不到。
-
“二维数组中的反转”是指交换同一行或同一列中的 2 个值吗?如果是,我认为 3x3 矩阵的结果应该是 18,而不是 19。
-
请澄清问题。
标签: java arrays algorithm inversion