编程之美-光影切割问题


package a;

public class DisorderCount {

/**《编程之美》“光影切割问题”
* 主要是两个问题:
* 1.数学公式(设定没有三条以上的直线交于同一点):
* 两条直线最多一个交点,将平面分成了4个区域;
* 三条直线最多三个交点,将平面分成了7个区域;
* 可以推出:N条直线 M个交点,区域数为N+M+1。
* 2.逆序数的分治求法:
* 交点M的个数就是逆序数对的对数。
* 例如左边的光线顺序是(1,2,3),右边是(3,2,1)。那么(3,1)(3,2)(2,1)共三个逆序数对,说明有三个交点。
* 归并排序来求逆序数。假设以下数据a1.a2.a3.a4分为两段,此时需要计算它们的逆序数,前半部分a1.a2,后半部分a3.a4.
* (这两个部分都是已经排好序的)。如果当前a1>a3,那么可以知道a2>a3,那么当前的逆序为2.即index(a2)-index(a1)+1.
* 将两个数组合并的时候,注意一下左边的数组有多少个数比右边的数组的多少数值要大
*/

private int count=0;

public static void main(String[] args) {
int[][] array={
{4,3,2,1},
{4,2,3,1},
{1,2,3,4},
{3,1,2},
{2},
};
for(int[] each:array){
DisorderCount test=new DisorderCount();
int count=test.disorderCount(each);
System.out.println(count);
}

}

public int disorderCount(int[] array){
if(array==null){
return -1;
}
if(array.length<2){
return 0;
}
disorderCountHelp(array,0,array.length-1);
return count;
}

public void disorderCountHelp(int[] array,int start,int end){
if(start<end){
int mid=start+(end-start)/2;
disorderCountHelp(array,start,mid);
disorderCountHelp(array,mid+1,end);
merge(array,start,mid,end);
}
}

public void merge(int[] array,int start,int mid,int end){
int i=start;
int j=mid+1;
int len=end-start+1;
int[] tmp=new int[len];
int k=0;
while(i<=mid&&j<=end){
if(array[i]<=array[j]){
tmp[k++]=array[i++];
}else{
tmp[k++]=array[j++];
count+=mid-i+1;//Each part is sorted.It means the data from a[i] to a[mid] is bigger than a[j].
}
}
while(i<=mid){
tmp[k++]=array[i++];
}
while(j<=end){
tmp[k++]=array[j++];
}
for(int m=0;m<k;m++){
array[start+m]=tmp[m];
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值