Sword는 제안(C++)-JZ51을 나타냅니다: 배열의 역순 쌍(알고리즘 - 정렬)

저자: Zhai Tianbao Steven
저작권 설명: 저작권은 저자에게 있습니다.상업적 전재의 경우 저자에게 허가를 요청하십시오.비상업적 전재의 경우 출처를 표시하십시오.

제목 설명:

배열의 두 숫자는 이전 숫자가 다음 숫자보다 크면 두 숫자가 역쌍을 이룹니다. 배열을 입력하고 이 배열에서 역방향 쌍의 총 수 P를 찾으십시오. 그리고 P 모듈로 1000000007의 결과를 출력합니다. 즉, 출력 P mod 1000000007
데이터 범위: 데이터의 50%에 대해 size≤104
데이터의 100%에 대해 size≤105

배열의 모든 숫자 값은 0≤val≤109를 만족합니다.

요구 사항: 공간 복잡도 O(n), 시간 복잡도 O(nlogn)

예:

입력하다:

[1,2,3,4,5,6,7,0]

반환 값:

7

문제 해결 아이디어:

이 문제에 대한 기존의 해결책은 폭력적인 방법이지만 이 문제는 nlogn의 복잡성이 필요하므로 병합 정렬로 해결할 수 있습니다.

  1. 병합 정렬을 정상적으로 작성하십시오.
  2. Combined Sorting 병합 및 정렬 과정에서 두 하위 구간의 데이터를 차례로 비교하여 새로운 순서를 재구성하는데 이때 왼쪽의 값 A가 오른쪽의 값 B보다 크면 A에서 중간 위치 C Add로 직접 데이터 수를 전송할 수 있습니다. 하위 범위가 정렬되었기 때문에 A가 B보다 크므로 A와 C 사이의 모든 데이터가 B보다 커야 하므로 역순 쌍이 형성될 수 있습니다.
  3. 이러한 방식으로 시간 복잡성은 주제의 요구 사항을 충족합니다.

테스트 코드:

class Solution {
public:
    int mod = 1000000007;
    // 归并排序
    int mergeSort(vector<int>& data, int left, int right){
        // 停止
        if(left >= right)
            return 0;
        // 中间位
        int mid = (left + right) / 2;
        // 拆分合并,累加逆序对数量
        int count = mergeSort(data, left, mid) + mergeSort(data, mid + 1, right);
        count %= mod;
        // 排序
        int i = left, j = mid + 1;
        vector<int> temp(data);
        for(int t = left; t <= right; ++t){
            // i如果到了mid+1,说明左子区间遍历完毕,后续直接取右区间数据即可
            if(i == mid + 1){
                data[t] = temp[j];
                j++;
            }
            // j如果到了right+1,说明右子区间遍历完毕,后续直接取左区间数据即可
            // 如果左侧值小于右侧值,不符合逆序对,正常排序即可
            else if(j == right + 1 || temp[i] <= temp[j]){
                data[t] = temp[i];
                i++;
            }
            // 如果左侧值大于右侧值,说明左侧当前位置到左子区间结束的数值,都大于该右侧值,直接计算数量:mid-i+1;然后正常排序
            // 这样操作降低了时间复杂度
            else{
                data[t] = temp[j];
                j++;
                count += mid - i + 1;
            }
        }
        return count % mod;
    }
    // 逆序对
    int InversePairs(vector<int>& nums) {
        int size = static_cast<int>(nums.size());
        int count = mergeSort(nums, 0, size - 1);
        return count;
    }
};

Supongo que te gusta

Origin blog.csdn.net/zhaitianbao/article/details/131371768
Recomendado
Clasificación