核心是递归,但是这个题里面还有一个亮点,就是把原来的被合并数组作为新的合并数组放进去,因为上一层递归的时候那个辅助数组是已经归并排好序了的,我们只要在上面的左右排好序的基础上,进行比较,和排序就可以了
算法的思想,这个题其实就是归并排序的一个变化
/****************************************************************************************
*题目:数组中的逆序对
* 在数组中的两个数字如果前面一个数字大于后面的数字,则这个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数
*时间:2015年10月3日10:17:32
*文件:InversePairs.java
*作者:cutter_point
****************************************************************************************/
package bishi.Offer50.y2015.m10.d03;
import org.junit.Test;
public class InversePairs
{
//输入一个数组进行统计
public int inversePairs(int data[])
{
if(data == null)
return 0;
//创建一个copy数组
int copy[] = new int[data.length];
copy = data.clone(); //这个类似吧data中的值复制一份到copy中,这时候copy中的值和data无关
int count = inversePairsCore(data, copy, 0, data.length - 1);
return count;
}
//这个题的核心其实就是归并排序
private int inversePairsCore(int data[], int copy[], int start, int end)
{
//当归并到最后单个元素的时候
if(start == end)
{
copy[start] = data[start]; //个人觉得这一步没什么用
return 0; //只剩一个元素的集合,是没有逆序对的
}//if
//归并就是把数组一分为二,那么每段的长度就是
int length = (end - start) / 2;
//左边和右边进行递归分解,这里是吧data做copy,copy做data,我觉得在函数里面建立辅助数组结果是一样的
//但是这里这样做可以节省空间,因为一篇空间得到了重复利用,虽然没什么用
int left = inversePairsCore(copy, data, start, start + length); //这个是左边的逆序对的个数
int right = inversePairsCore(copy, data, start + length + 1, end); //右边数组的逆序对的个数
//接下来我们对这个数组中的你需对进行统计,我们设定3个游标
int i = start + length, j = end, indexCopy = end;
//设定一个参数用来统计逆序对的个数
int count = 0;
//这个里面对数据进行遍历统计
while(i >= start && j >= start + length + 1)
{
//进行判断,前面的数组中的数据是否比后面的数组中的数大
if(data[i] > data[j])
{
//这里的操作要求data排好序,那么这里的copy数组还是有必要进行传参的
copy[indexCopy--] = data[i--];
count += j - start - length;
//输出逆序对
for(int k = j; k >= start + length + 1; --k)
{
System.out.print("{" + data[i + 1] + "<==>" + data[k] + "}\t");
}//for
}//if
else
{
//如果左边比右边小点话,那么直接加入到辅助数组中
copy[indexCopy--] = data[j--];
}//else
}//while
//把剩下的元素都放到辅助数组中
for(; i >= start; --i)
{
copy[indexCopy--] = data[i];
}//for
for(; j >= start + length + 1; --j)
{
copy[indexCopy--] = data[j];
}//for
//返回逆序对个数
return left + right + count;
}
@Test
public void test()
{
int a[] = {1,2,3,4,5,6};
int b[] = a.clone();
a[1] = 10;
for(int i = 0; i < a.length; ++i)
{
System.out.println(b[i]);
}
System.out.println("逆序对有:");
InversePairs ip = new InversePairs();
int data[] = {7,5,6,4};
System.out.println("\n" + ip.inversePairs(data));
}
}