首页 > 代码库 > 剑指offer_数组中的逆序对

剑指offer_数组中的逆序对

题目描述

  在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。
并将P对1000000007取模的结果输出。 即输出P%1000000007 
  
  本题采用归并排序,归并排序算法我在前一篇博客里写到过,在那个基础上进行修改即可!(强烈建议先理解归并排序的具体算法后,再来做此题)
public class Solution36 {
    private int count = 0; //记录次数
    private int[] copy ; 
    public int InversePairs(int [] array) {
        if(array.length == 0) return 0;

       copy =  new int[array.length];

        sort(array, 0, array.length-1);
        return count%1000000007;

    }
    
    private void sort(int[] array, int start, int end) {

        if(end <= start) return;
        //int mid = start + (end - start) / 2;
        int mid = (end+start) /2; 
        sort(array, start, mid);//左边数组排序
        sort(array, mid + 1, end);//右边数组排序

        merge(array,start,mid, end); //归并方法
    }
    /**
     * 排序
     * @param array 需要排序的数组
     * @param start 数组的起始位置
     * @param mid 数组的中间位置
     * @param end
     */
    private void merge(int[] array, int start, int mid, int end) {

        int i = start, j = mid + 1; //将数组分割成两段,由于归并排序特点,前后两段是有序的

        for(int k = start; k <= end; k++){ //复制数组
            copy[k] = array[k];
        }

        for(int k= start; k<= end; k++){
            if(i > mid) array[k] = copy[j++]; //当只剩下右边数组
            else if(j > end) array[k] = copy[i++]; //当只剩下左边数组
            else if(copy[i] > copy[j]) {//当前一个数组的数大于后一个数组的数时,逆序(前后数组分界点为mid)
                /**
                 * 例如数组5 6 7 2 4 8进行归并 ,因为归并排序会使数组前后数组有序
                 * 前一个数组为:5 6 7 ,后一个数组为: 2 4 8
                 * 当 5 大于 2时,5后面的6,7都会大于2, 且5的最后一个数组下标为mid,
                 * 所以count = count+ mid - i + 1 然后将2添加到array[k]中
                 */
                count = (count + mid-i + 1)%1000000007; 
                array[k] = copy[j++];
            }else {
                array[k] = copy[i++];
            }
        }

    }
}

测试代码:

1   public static void main(String[] args){
2         Solution36 solution36 = new Solution36();
3         int[] array = new int[]{3,3,2,4,2,1};
4         int count = solution36.InversePairs(array);
5         System.out.println(count);
6         for (Integer i: array) {
7             System.out.print(i + " ");
8         }
9     }

 

 
 

剑指offer_数组中的逆序对