【编程题】数组中的逆序对(java语言)

本文介绍了一种高效算法,用于计算数组中逆序对的数量。采用归并排序思想,在合并过程中统计逆序对,实现O(nlogn)的时间复杂度。同时提供了简单易懂的Java代码实现。

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

【编程题】数组中的逆序对(java语言)

题目描述

有一组数,对于其中任意两个数组,若前面一个大于后面一个数字,则这两个数字组成一个逆序对。请设计一个高效的算法,计算给定数组中的逆序对个数。
给定一个int数组A和它的大小n,请返回A中的逆序对个数。保证n小于等于5000。

测试样例:

[1,2,3,4,5,6,7,0],8
返回:7

***方法一***归并方法

思路讲解:
①归并思路
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
**归并图**
②利用归并排序,在对有序子数组进行merge的同时,累加逆序对,时间复杂度O(nlogn)
代码

   import java.util.*;
    public class AntiOrder {
        public int count(int[] A, int n) {
            // write code here
            int[] copy=new int[n];
            for(int i=0;i<n;i++)
                copy[i]=A[i];
           return sortCore(A,copy,0,n-1);
        }
        int sortCore(int[] A,int[] copy,int low,int high){
            if(low>=high){
                copy[low]=A[low];
                return 0;
            }
            int mid=(low+high)>>1;
            int left=sortCore(copy,A,low,mid);
            int right=sortCore(copy,A,mid+1,high);
            int i=mid,j=high,index=high;
            int count=0;
            while(i>=low&&j>=mid+1){
                if(A[i]>A[j]){
                   count+=j-mid;
                   copy[index--]=A[i--];
                }else
                    copy[index--]=A[j--];
            }
            while(i>=low)
               copy[index--]=A[i--];
            while(j>=mid+1)
               copy[index--]=A[j--];
            return count+left+right;
        }
    }

包含main输入的代码

import java.util.ArrayList;
import java.util.Scanner;
public class Main5 {
    public static void main(String[] args) {
        int[] A={1,2,3,4,5,6,7,0};
        int count= count( A,A.length);
        System.out.println(count);
    }
        public static int count(int[] A, int n) {
            // write code here
            int[] copy=new int[n];
            for(int i=0;i<n;i++)
                copy[i]=A[i];
            return sortCore(A,copy,0,n-1);
        }
      private static int sortCore(int[] A,int[] copy,int low,int high){
            if(low>=high){
                copy[low]=A[low];
                return 0;
            }
            int mid=(low+high)>>1;
            int left=sortCore(copy,A,low,mid);
            int right=sortCore(copy,A,mid+1,high);
            int i=mid,j=high,index=high;
            int count=0;
            while(i>=low&&j>=mid+1){
                if(A[i]>A[j]){
                    count+=j-mid;
                    copy[index--]=A[i--];
                }else
                    copy[index--]=A[j--];
            }
            while(i>=low)
                copy[index--]=A[i--];
            while(j>=mid+1)
                copy[index--]=A[j--];
            return count+left+right;
        }
}

***方法二***暴力解法

思路讲解
直接两次循环遍历,比较是否为逆序
代码

import java.util.*;
public class AntiOrder {
    public int count(int[] A, int n) {
        // write code here
        int result = 0;
        for(int i = 1;i < n;i++){
            for(int j = 0;j<i;j++){
                if (A[j] > A[i])
                    result++;
            }
        }
        return result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值