逆序对问题(Java实现)归并详解

 更新时间:2026年05月09日 11:52:14   作者:-添砖Java  
文章介绍了计算给定正整数序列中逆序对数量的方法,特别是使用归并排序进行拆分和合并时统计逆序对,通过递归拆分序列,并在合并过程中统计逆序对数量,从而得到整个序列的逆序对总数,此方法能有效处理包含重复数字的序列

题目

对于给定的一段正整数序列,逆序对就是序列中ai>aj,且i<j的有序对;注意序列中可能有重复数字,并分析算法的时间性能。

例如:有6个数字,分别是5,4,2,6,3,1,则逆序对数目是11。

思想

一个乱序的数组,使用归并排序的方法对其进行拆分拆分,最后剩余两个已经排好序的数组(如图1)

  • ​图1:

然后对两个数组再进行归并排序,排序的同时统计逆序对,比如2与1对比可以产生逆序对,则4与1、5与1也能产生逆序对,按照此思路即可统计出所有的逆序对。

代码:

package com.itwyc;

import java.util.*;

public class Main {
    public static long count = 0;   // 逆序对个数
    public static void getCount(int[] nums) {
        if (nums.length > 1) {
            int[] left_temp = getLeftTemp(nums, 0); // 得到左边数组           
            int[] right_temp = getLeftTemp(nums, 1);// 得到右边数组              
            getCount(left_temp); // 将得到的数组继续拆分                                   
            getCount(right_temp);
            merge(nums, left_temp, right_temp);// 归并排序,归并的同时统计逆序对                     
        }
    }

    public static int[] getLeftTemp(int[] temp, int a) {
        int[] current;
        if (a == 0) {
            current = new int[temp.length / 2];
            for (int i = 0; i < temp.length / 2; i++) {
                current[i] = temp[i];
            }
        } else {
            current = new int[temp.length - temp.length / 2];
            for (int i = 0; i < temp.length - temp.length / 2; i++) {
                current[i] = temp[temp.length / 2 + i];
            }
        }
        return current;
    }

    public static void merge(int[] nums, int[] left_temp, int[] right_temp) {
        int index = 0;
        int left = 0;
        int right = 0;
        int left_len = left_temp.length;
        int right_len = right_temp.length;
        while (left < left_len && right < right_len) {// 如果左边的数大于右边的数,则为逆序对                   
            if (left_temp[left] > right_temp[right]) {
                count += (left_len - left);// 如果此数为逆序对,则此数右边的数也为逆序对,因为两个数组内已经排好序                              
                nums[index++] = right_temp[right++];
            } else {
                nums[index++] = left_temp[left++];
            }
        }
        while (left < left_len) {
            nums[index++] = left_temp[left++];
        }
        while (right < right_len) {
            nums[index++] = right_temp[right++];
        }
    }

    public static void main(String[] args) {

        /**
         *  逆序对问题
         */
        int[] nums = {8, 7, 6, 5, 4, 3, 2, 1};
        getCount(nums);
        System.out.println("逆序对有" + count + "个.");
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用GraalVM如何将SpringBoot项目打包成exe

    使用GraalVM如何将SpringBoot项目打包成exe

    本文介绍了如何使用GraalVM和Maven将Spring Boot项目打包成可执行文件的步骤,并详细解释了在打包过程中遇到的常见错误及其解决方法
    2024-12-12
  • Springboot实现推荐系统的协同过滤算法

    Springboot实现推荐系统的协同过滤算法

    协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot实现推荐系统的协同过滤算法,感兴趣的朋友一起看看吧
    2025-05-05
  • 分享一个你不知道的Java异常实现的缺陷

    分享一个你不知道的Java异常实现的缺陷

    Java中一个大家熟知的知识点就是异常捕获,try...catch...finally组合,但是很多人不知道这里面有一个关于Java的缺陷,或者说是异常实现的一点不足之处。本文就通过一个很简单的实验给大家演示下效果玩玩儿,希望大家能觉得有趣
    2022-12-12
  • Mac OS上安装Tomcat服务器的简单步骤

    Mac OS上安装Tomcat服务器的简单步骤

    这篇文章主要介绍了Mac OS上安装Tomcat服务器的简单步骤,包括简单的启动命令和查看Tomcat信息的方法,需要的朋友可以参考下
    2015-11-11
  • 浅谈Java自定义注解相关知识

    浅谈Java自定义注解相关知识

    今天带大家来学习Java注解的相关知识,文中对自定义注解作了非常详细的介绍,对正在学习Java的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05
  • java8新特性 获取list某一列的操作

    java8新特性 获取list某一列的操作

    这篇文章主要介绍了java8新特性 获取list某一列的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • 关于SpringBoot2.7.6连接nacos遇到的一些问题

    关于SpringBoot2.7.6连接nacos遇到的一些问题

    这篇文章主要介绍了关于SpringBoot2.7.6连接nacos遇到的一些问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • SpringBoot项目启动失败的常见错误总结

    SpringBoot项目启动失败的常见错误总结

    文章总结了SpringBoot项目启动失败的常见错误及其解决方法,涵盖了项目识别与依赖问题、配置文件问题、环境配置问题、依赖与Bean注入问题、数据库连接问题、启动类问题以及其他常见问题,需要的朋友可以参考下
    2025-11-11
  • mybatis自动生成@Table、@Column、@Id注解的方法

    mybatis自动生成@Table、@Column、@Id注解的方法

    这篇文章主要介绍了mybatis自动生成@Table、@Column、@Id注解的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Java实现md5和base64加密解密的示例代码

    Java实现md5和base64加密解密的示例代码

    这篇文章主要介绍了Java实现md5和base64加密解密的示例代码,帮助大家更好的利用Java加密解密文件,感兴趣的朋友可以了解下
    2020-09-09

最新评论