剑指offer---数组中的逆序对

题目:数组中的逆序对

要求:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007


输入:

  • {7, 5, 6, 4}

逆序对:

  • {7, 5}
  • {7, 6}
  • {7, 4}
  • {5, 4}
  • {6, 4}

输出:

  • 5

class Solution {
public:
    int InversePairs(vector<int> data) {
        
    }
};

解题代码:

class Solution {
public:
    int InversePairs(vector<int> data) {
        int count = 0;
        int len = data.size();
        for(int seg = 1; seg <= len; seg *= 2){
            for(int start = 0; start <= len; start += 2 * seg){
                int low = start;
                int mid = min(start + seg - 1, len-1);
                int high = min(start + 2 * seg - 1, len-1);
                /**
                 * 利用归并排序思想:
                 * 把待排序部分data[low,...,high]分成前后两部分,每部分长度为seg
                 * 前一部分:data[start1,...,end1]
                 * 后一部分:data[start2,...,end2]
                 */
                int start1 = low, end1 = mid;
                int start2 = end1 + 1, end2 = high;
                deque<int> q; // 将data数组从low到high元素的排序结果存储在q中

                while(end1 >= start1 && end2 >= start2){
                    if(data[end1] > data[end2]){
                        count = count + end2 - start2 + 1;
                        if(count >= 1000000007) // 数值过大求余
                            count %= 1000000007;
                        q.push_front(data[end1--]);
                    }
                    else
                        q.push_front(data[end2--]);
                }
                // 剩余部分
                while(start1 <= end1)
                    q.push_front(data[end1--]);
                while(start2 <= end2)
                    q.push_front(data[end2--]);

                //  将从low到high的排序结果在data数组中更新
                for(deque<int>::iterator it = q.begin(); it != q.end(); it++)
                    data[start1++] = *it;
                q.shrink_to_fit();
            }
        }
        return count;
    }
};
原文地址:https://www.cnblogs.com/iwangzhengchao/p/9966359.html