• 剑指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     }
     
     
  • 相关阅读:
    I/O多路复用技术
    网络编程的异常及处理
    LINUX的signal
    网络编程小知识
    一个位压缩技巧
    加密技术[翻译]
    暴雪的hash算法[翻译]
    喜欢就好
    【PYTHON】编码是个细致活
    【Python3】POP3协议收邮件
  • 原文地址:https://www.cnblogs.com/huangyichun/p/6089737.html
Copyright © 2020-2023  润新知