「归并思想」归并思想中的第二个函数merge可以应用到其他问题中

来源:互联网 发布:采购流程优化的趋势 编辑:程序博客网 时间:2024/06/03 16:52

归并排序知识点

时间复杂度

归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它的时间复杂度是O(n*log2n)。

空间复杂度

由前面的算法说明可知,算法处理过程中,需要一个大小为n的临时存储空间用以保存合并序列。

算法稳定性

在归并排序中,相等的元素的顺序不会改变,所以它是稳定的算法。

归并排序和堆排序、快速排序的比较

若从空间复杂度来考虑:首选堆排序,其次是快速排序,最后是归并排序。

若从稳定性来考虑,应选取归并排序,因为堆排序和快速排序都是不稳定的。

若从平均情况下的排序速度考虑,应该选择快速排序。 

void Merge(vector<int> &nums, int start, int middle, int end, vector<int> &buffer){    int i = start;    int j = middle + 1;    int k = start;    while(i <= middle && j <= end)    {        if(nums[i] <= nums[j])            buffer[k++] = nums[i++];        else buffer[k++] = nums[j++];    }    while(i <= middle)        buffer[k++] = nums[i++];    while(j <= end)        buffer[k++] = nums[j++];    for(i = start; i <= end; ++i)        nums[i] = buffer[i];}void MergeSort(vector<int> &nums, int start, int end, vector<int> &buffer){    if(start >= end) return;    int middle = (start & end) + ((start ^ end) >> 1);    MergeSort(nums, start, middle, buffer);    MergeSort(nums, middle+1, end, buffer);    Merge(nums, start, middle, end, buffer);}void print(const vector<int> &nums){    for(int i = 0; i < nums.size(); ++i)        cout<<nums[i]<<" ";    cout<<endl;}void MergeMain(vector<int> &nums){    int size = nums.size();    if(size <= 1) return;    vector<int> buffer(size, 0);    MergeSort(nums, 0, size-1, buffer);}int main(){    int arr[] = {        8, 10, 9, 3, 7, 8, 9, 4, 6, 2, 5    };    vector<int> nums(arr, arr + sizeof(arr)/sizeof(int));    MergeMain(nums);    print(nums);    return 0;}

LintCode Problem:  The Smallest Difference
/*************************************************************************> File Name: TheSmallestDifference.cpp> Author: Shaojie Kang> Mail: kangshaojie@ict.ac.cn > Created Time: 2015年09月07日 星期一 14时50分51秒     > Problem:        Given two array of integers(the first array is array A, the second array is array B), now we are going         to find a element in array A which is A[i], and another element in array B which is B[j], so that the         difference between A[i] and B[j] (|A[i] - B[j]|) is as small as possible, return their smallest difference.        Have you met this question in a real interview? Yes        Example        For example, given array A = [3,6,7,4], B = [2,8,9,3], return 0        Challenge        O(n log n) time     > Solution 1:        Step 1: sort the two arrays;        Step 2: use two pointers i and j which correspodingly point to the two arrays     > Solution 2:        use Binary Search, STL function lower_bound ************************************************************************/#include<iostream>#include<vector>#include<algorithm>#include<cstdlib>using namespace std;// Solution 1: use two pointersint smallestDifference(vector<int> &A, vector<int> &B){    int size1 = A.size();    int size2 = B.size();    if(A.empty() || B.empty()) return -1;    sort(A.begin(), A.end());    sort(B.begin(), B.end());    int i = 0, j = 0;    int smallestDiff = abs(A[0] - B[0]);    while(i < size1 && j < size2)    {        int diff = abs(A[i] - B[j]);        smallestDiff = min(smallestDiff, diff);        if(A[i] == B[j]) return 0;        else if(A[i] < B[j]) i++;        else j++;    }    return smallestDiff;}// Solution 2: use Binary Search int smallestDifference2(vector<int> &A, vector<int> &B){    int sizeA = A.size();    int sizeB = B.size();    if(sizeA == 0 || sizeB == 0) return -1;    sort(B.begin(), B.end());    int smallestDiff = abs(A[0] - B[0]);    for(int i = 0; i < sizeA; ++i)    {        int position = lower_bound(B.begin(), B.end(), A[i]) - B.begin();        if(position != sizeB)            smallestDiff = min(smallestDiff, abs(A[i] - B[position]));        if(position != sizeB - 1)            smallestDiff = min(smallestDiff, abs(A[i] - B[position + 1]));                   if(position != 0)            smallestDiff = min(smallestDiff, abs(A[i] - B[position-1]));               }    return smallestDiff;}




0 0
原创粉丝点击