归并排序及延伸问题

1.归并排序算法

算法步骤:将数组一直拆分成l-mid-right 如,二分查找,快速排序这些。 

看完小数和和逆序对问题,也不需要看归并排序的代码了。这两个问题,只是在归并的基础上,进行了额外的处理。计算了count值。

2.归并排序问题-小和问题

一个数,他前面的数字比他小的都累加起来 叫他小数和

public class Solution {
    int count = 0;
    public int InversePairs(int [] array) {
        //求一个数右边有多少个数比她小
        sort(array,0,array.length-1);
        return count;
    }
    public void sort(int [] array,int left,int right){
        if(left >= right){
            return;
        }
        int midle = (left+right)>>1;
        sort(array,left,midle);
        sort(array,midle+1,right);
        merge(array,left,midle,right);
    }
    
    public void merge(int [] array,int left,int midle,int right){
        //还是要排序,排序的过程的  判断  来个递减序列   //先来递增吧。。。
        int[] help = new int[right-left+1];
        int mm = midle+1;
        int start = left;
        int index= 0;
        while(left<= midle && mm <= right){
            if(array[left]<=array[mm]){
                //找到比mm小的了  所以mm右边都比这个数大
                count+= (right-mm+1)*array[left];
                help[index++]= array[left++];
            }else{
                help[index++]= array[mm++];
            }
        }
        //剩下来的都是小的。
        while(left<= midle){
            help[index++] = array[left++];
        }
        while(mm <= right){
            help[index++]= array[mm++];
        }
        index = 0;
        while(start<=right){
            array[start++] = help[index++];
        }
    }
}

 

3.归并排序问题-逆序对问题

输入:

[1,2,3,4,5,6,7,0]  一个数,他后面的数字比她小,就形成一个逆序对,形如:1,0    2,0

返回值:

7
public class Solution {
    int count = 0;
    public int InversePairs(int [] array) {
        //求一个数右边有多少个数比她小
        sort(array,0,array.length-1);
        return count;
    }
    public void sort(int [] array,int left,int right){
        if(left >= right){
            return;
        }
        int midle = (left+right)>>1;
        sort(array,left,midle);
        sort(array,midle+1,right);
        merge(array,left,midle,right);
    }
    
    public void merge(int [] array,int left,int midle,int right){
        //还是要排序,排序的过程的  判断  来个递减序列   //先来递增吧。。。
        int[] help = new int[right-left+1];
        int mm = midle+1;
        int start = left;
        int index= 0;
        while(left<= midle && mm <= right){
            if(array[left]<=array[mm]){
                help[index++]= array[left++];
            }else{
                 //如果right有可能剩余,这里也包括进去了 ,
                //对于逆序对问题只有这里相对于归并排序有所变动
                count+= (midle-left+1);
                count %= 1000000007;
                help[index++]= array[mm++];
            }
        }
        //剩下来的都是小的。
        while(left<= midle){
            help[index++] = array[left++];
        }
        while(mm <= right){
            help[index++]= array[mm++];
        }
        index = 0;
        while(start<=right){
            array[start++] = help[index++];
        }
    }
}

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值