剑指offer_数组中的逆序对

本文介绍了一种使用归并排序算法计算数组中逆序对总数的方法,并通过一个具体示例展示了如何实现这一过程。文章提供了完整的Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

  在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数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     }

 

 
 

转载于:https://www.cnblogs.com/huangyichun/p/6089737.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值