Data structure notes--merge sort and its extended questions (small sum problem, reverse order pair problem)

Table of contents

1--merge sort

2--Small and problem

3--Reverse order pair problem


1--merge sort

        The core idea of ​​merge sort: Merge and sort an unordered sequence into an ordered series; Divide the unordered sequence into two by recursion , and merge and sort the binary sequence into an ordered sequence from the bottom layer ;

#include <iostream>
#include <vector>

class Solution{
public:
    std::vector<int> Merge_Sort(std::vector<int> arr){
        if(arr.size() <= 1) return arr;
        split(arr, 0, arr.size() - 1);
        return arr;
    }

    // 二分
    void split(std::vector<int> &arr, int l, int r){
        if(l == r) return;
        int mid = l + (r - l) / 2;
        split(arr, l, mid);
        split(arr, mid+1, r);
        // 归并
        merge(arr, l, mid, mid+1, r);
    }

    void merge(std::vector<int> &arr, int l1, int r1, int l2, int r2){
        std::vector<int> res;
        int i = l1, j = l2;
        while(i <= r1 && j <= r2){
            if (arr[i] < arr[j]){
                res.push_back(arr[i]);
                i++;
            }
            else{
                res.push_back(arr[j]);
                j++;
            }
        }
        while(i <= r1){
            res.push_back(arr[i]);
            i++;
        }
        while(j <= r2){
            res.push_back(arr[j]);
            j++;
        }
        for(int i = 0, j = l1; j <= r2; i++, j++){
            arr[j] = res[i];
        }
    }
};

int main(){
    std::vector<int> input = {1, 3, 4, 2, 5};
    Solution S1;
    std::vector<int> res = S1.Merge_Sort(input);
    for(int num : res) std::cout << num << " ";
    return 0;
}

2--Small and problem

        In an array, the numbers to the left of each number that are smaller than the current number are added together, which is called the small sum of the array. Please code to solve the small sum of an array;

        Example, given the array [1, 3, 4, 2, 5], the number on the left of 1 smaller than 1 is none; the number on the left of 3 smaller than 3 is 1; the number on the left of 4 smaller than 4 is 1 and 3 ; The number on the left of 2 smaller than 2 is 1; the number on the left of 5 smaller than 5 is 1, 3, 4 and 2; therefore the sum of decimals in the array is: 1 + (1+3) + (1) + (1 +3+4+2) = 16;

Main ideas:

        When merging and sorting compares the elements of two arrays, the corresponding decimal sum is determined; the specific method is to analyze how many decimals the current number is in another array , that is, how many times the current number is used to calculate the decimal sum ;

#include <iostream>
#include <vector>

class Solution{
public:
    int Merge_Sort(std::vector<int> arr){
        if(arr.size() <= 1) return 0;
        int sum = split(arr, 0, arr.size() - 1);
        return sum;
    }

    // 二分
    int split(std::vector<int> &arr, int l, int r){
        if(l == r) return 0;
        int mid = l + (r - l) / 2;
        int count1 = split(arr, l, mid);
        int count2 = split(arr, mid+1, r);
        int count3 = merge(arr, l, mid, mid+1, r);
        // 归并
        return count1 + count2 + count3;
    }

    int merge(std::vector<int> &arr, int l1, int r1, int l2, int r2){
        int sum = 0;
        std::vector<int> res;
        int i = l1, j = l2;
        while(i <= r1 && j <= r2){
            if (arr[i] < arr[j]){
                // 对于 arr[j, r2] 的数都会大于 arr[i],因此它们的小数和都包含arr[i]
                sum += (r2 - j + 1) * arr[i];
                res.push_back(arr[i]);
                i++;
            }
            else{
                res.push_back(arr[j]);
                j++;
            }
        }
        while(i <= r1){
            res.push_back(arr[i]);
            i++;
        }
        while(j <= r2){
            res.push_back(arr[j]);
            j++;
        }
        for(int i = 0, j = l1; j <= r2; i++, j++){
            arr[j] = res[i];
        }

        return sum;
    }
};

int main(){
    std::vector<int> input = {1, 3, 4, 2, 5};
    Solution S1;
    int res = S1.Merge_Sort(input);
    std::cout << res << " " << std::endl;
    return 0;
}

3--Reverse order pair problem

Main ideas:

        When merging and sorting compares the elements of two arrays in pairs, the corresponding reverse sequence pair is determined; the specific method is to analyze how many reverse sequence numbers the current number (arr2) has in another array (arr1) ;

#include <iostream>
#include <vector>

class Solution{
public:
    int Merge_Sort(std::vector<int> arr){
        if(arr.size() <= 1) return 0;
        int sum = split(arr, 0, arr.size() - 1);
        return sum;
    }

    // 二分
    int split(std::vector<int> &arr, int l, int r){
        if(l == r) return 0;
        int mid = l + (r - l) / 2;
        int count1 = split(arr, l, mid);
        int count2 = split(arr, mid+1, r);
        int count3 = merge(arr, l, mid, mid+1, r);
        // 归并
        return count1 + count2 + count3;
    }

    int merge(std::vector<int> &arr, int l1, int r1, int l2, int r2){
        int sum = 0;
        std::vector<int> res;
        int i = l1, j = l2;
        while(i <= r1 && j <= r2){
            if (arr[i] > arr[j]){
                // 对于 arr[j, r2] 的数都会大于 arr[i],因此它们的小数和都包含arr[i]
                sum += (r1 - i + 1);
                res.push_back(arr[j]);
                j++;
            }
            else{
                res.push_back(arr[i]);
                i++;
            }
        }
        while(i <= r1){
            res.push_back(arr[i]);
            i++;
        }
        while(j <= r2){
            res.push_back(arr[j]);
            j++;
        }
        for(int i = 0, j = l1; j <= r2; i++, j++){
            arr[j] = res[i];
        }

        return sum;
    }
};

int main(){
    std::vector<int> input = {7, 5, 6, 4};
    Solution S1;
    int res = S1.Merge_Sort(input);
    std::cout << res << " " << std::endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43863869/article/details/132136121