好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

java实现数组中的逆序对

在 数组 中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个 逆序对 ,例如在数组{7,5,6,4}中,一共存在5对逆序对,分别是{7,6},{7,5},{7,4},{6,4},{5,4}。输入一个数组,求出这个数组中的逆序对的总数p。并将p对1000000007取模的结果输出。,即输出p%1000000007。

代码

解法一

暴力简单低效,不会改变原数组

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public static int inversepairs( int [] array) {

     if (array == null || array.length < 2 ) {

       return 0 ;

     }

     int count = 0 ;

     for ( int i = 0 ; i < array.length; i++) {

       for ( int j = i + 1 ; j < array.length; j++) {

         if (array[i] > array[j]) {

           count++;

         }

       }

     }

     return count % 1000000007 ;

   }

解法二

利用数组的归并排序,高效,但是会改变原数组

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

public static int inversepairs2( int [] array) {

     if (array == null || array.length < 2 ) {

       return 0 ;

     }

     int count = mergesort(array, 0 , array.length - 1 );

     return count % 1000000007 ;

   }

 

   private static int mergesort( int [] array, int start, int end) {

     if (start >= end) {

       return 0 ;

     }

 

     // 找到数组的中点,分割为两个子数组,递归求解

     int middle = (start + end) / 2 ;

     int left = mergesort(array, start, middle);

     int right = mergesort(array, middle + 1 , end);

 

     // 存储归并后的数组

     int [] copy = new int [array.length];

     system.arraycopy(array, start, copy, start, end - start + 1 );

     // 从两个子数组的尾部开始遍历

     int i = middle;

     int j = end;

     int copyindex = end;

     // 记录逆序对的数量

     int count = 0 ;

 

     while (i >= start && j >= middle + 1 ) {

       // 数组是升序的

       // 如果左边数组比右边数组大,则将大的放入存储数组中

       // 并且累加逆序对,应为是有序的,所以左边数组的第i个元素比第j个及其之前的数都大

       if (array[i] > array[j]) {

         copy[copyindex--] = array[i--];

         count += (j - middle);

       } else {

         copy[copyindex--] = array[j--];

       }

     }

 

     // 将子数组剩余的部分一次写入归并后的存储数组

     while (i >= start) {

       copy[copyindex--] = array[i--];

     }

     while (j >= middle + 1 ) {

       copy[copyindex--] = array[j--];

     }

 

     // 将本次两个子数组的合并写入原数组中

     for ( int k = start; k <= end ; k++) {

       array[k] = copy[k];

     }

     return left + right + count;

   }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://blog.csdn.net/zl18310999566/article/details/80228859

查看更多关于java实现数组中的逆序对的详细内容...

  阅读:12次