题目来源:《剑指offer》面试题36
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这两个数组中的逆序对的总数。例如数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6),(7,5),(7,4),(6,4)和(5,4)。
下面把《剑指offer》的分析贴上来:
代码:
int CountInversionPair(vector<int>& nums) { if (nums.size() <= 1) return 0; int count = 0; CountInversionPair(nums, 0, nums.size() - 1, count); return count; } void CountInversionPair(vector<int> &nums, int start_pos, int end_pos, int &count) { if (start_pos >= end_pos) return; int mid = start_pos + (end_pos - start_pos) / 2; CountInversionPair(nums, start_pos, mid, count); CountInversionPair(nums, mid + 1, end_pos, count); Merge(nums, start_pos, mid, end_pos, count); } void Merge(vector<int>& nums, int start_pos, int mid, int end_pos, int &count) { if (start_pos == end_pos) return; vector<int> temp_nums(end_pos - start_pos + 1); int left_index = mid; int right_index = end_pos; int original_index = end_pos - start_pos; while (left_index >= start_pos && right_index > mid) { if (nums[left_index] > nums[right_index]) { count += right_index - mid; temp_nums[original_index--] = nums[left_index--]; } else { temp_nums[original_index--] = nums[right_index--]; } } for (; left_index >= start_pos; left_index--) temp_nums[original_index--] = nums[left_index]; for (; right_index > mid; right_index--) temp_nums[original_index--] = nums[right_index]; for (int i = start_pos, j = 0; i <= end_pos; i++) { nums[i] = temp_nums[j++]; } }