您的位置:首页 > 其它

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

2015-09-08 16:10 281 查看
归并排序知识点

时间复杂度

归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它的时间复杂度是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 pointers
int 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: