[题解]《算法零基础100讲》(第36讲) 排序进阶 - 归并排序

源码剖析

归并排序,就是不断地利用归并来进行排序。也就是说对于一段需要排序的区间,先对其左右半段进行排序,然后利用一个新数组用来合并两个数组,用两根指针分别指向左右半段未利用的第一个值,依次将两根指针指向的数字比较小的一个放进用来合并的数组。最后把用来合并的数组中的值放回原数组对应位置。

void merge_sort(vector<int>&n,int l,int r) {
    if(l>=r) return;
    //如果当前区间不包含或是只包含一个元素,直接结束这一次的排序过程
    vector<int>m;
    //用来存放合并值的临时数组
    int mid=l+r>>1;
    //计算一个中间值来分开左右两边
    merge_sort(n,l,mid),merge_sort(n,mid+1,r);
    //递归对左右两边进行排序
    int i,j;
    //i、j是左右两根指针,分别指向左右两边下一个没放进临时数组的元素
    for(i=l,j=mid+1;i<=mid&&j<=r;) {
        if(n[i]<n[j]) m.push_back(n[i++]);
        else m.push_back(n[j++]);
        //那个元素小就把那个元素放进临时数组,用完那根指针的对应值记得给指针往后移一个
    }
    while(i<=mid) m.push_back(n[i++]);
    while(j<=r) m.push_back(n[j++]);
    //处理某一边的元素没有全部放进临时数组中
    for(i=0,j=l;i<m.size();i++,j++) n[j]=m[i];
    //把临时数组中的值还回原数组(这时临时数组中就存放了当前排序区间的排序结果)
}

164. 最大间距

class Solution {
public:
    void merge_sort(vector<int>&n,int l,int r) {
        if(l>=r) return;
        vector<int>m;
        int mid=l+r>>1;
        merge_sort(n,l,mid),merge_sort(n,mid+1,r);
        int i,j;
        for(i=l,j=mid+1;i<=mid&&j<=r;) {
            if(n[i]<n[j]) m.push_back(n[i++]);
            else m.push_back(n[j++]);
        }
        while(i<=mid) m.push_back(n[i++]);
        while(j<=r) m.push_back(n[j++]);
        for(i=0,j=l;i<m.size();i++,j++) n[j]=m[i];
    }

    int maximumGap(vector<int>& nums) {
        merge_sort(nums,0,nums.size()-1);
        int ans=0;
        for(int i=1;i<nums.size();i++) {
            ans=max(ans,nums[i]-nums[i-1]);
        }
        return ans;
    }
};

912. 排序数组

class Solution {
public:
    void merge_sort(vector<int>&n,int l,int r) {
        if(l>=r) return;
        vector<int>m;
        int mid=l+r>>1;
        merge_sort(n,l,mid),merge_sort(n,mid+1,r);
        int i,j;
        for(i=l,j=mid+1;i<=mid&&j<=r;) {
            if(n[i]<n[j]) m.push_back(n[i++]);
            else m.push_back(n[j++]);
        }
        while(i<=mid) m.push_back(n[i++]);
        while(j<=r) m.push_back(n[j++]);
        for(i=0,j=l;i<m.size();i++,j++) n[j]=m[i];
    }
    vector<int> sortArray(vector<int>& nums) {
        merge_sort(nums,0,nums.size()-1);
        return nums;
    }
};

217. 存在重复元素

class Solution {
public:
    void merge_sort(vector<int>&n,int l,int r) {
        if(l>=r) return;
        vector<int>m;
        int mid=l+r>>1;
        merge_sort(n,l,mid),merge_sort(n,mid+1,r);
        int i,j;
        for(i=l,j=mid+1;i<=mid&&j<=r;) {
            if(n[i]<n[j]) m.push_back(n[i++]);
            else m.push_back(n[j++]);
        }
        while(i<=mid) m.push_back(n[i++]);
        while(j<=r) m.push_back(n[j++]);
        for(i=0,j=l;i<m.size();i++,j++) n[j]=m[i];
    }
    bool containsDuplicate(vector<int>& nums) {
        merge_sort(nums,0,nums.size()-1);
        for(int i=1;i<nums.size();i++)
            if(nums[i]==nums[i-1]) return true;
        return false;
    }
};

169. 多数元素

class Solution {
public:
    void merge_sort(vector<int>&n,int l,int r) {
        if(l>=r) return;
        vector<int>m;
        int mid=l+r>>1;
        merge_sort(n,l,mid),merge_sort(n,mid+1,r);
        int i,j;
        for(i=l,j=mid+1;i<=mid&&j<=r;) {
            if(n[i]<n[j]) m.push_back(n[i++]);
            else m.push_back(n[j++]);
        }
        while(i<=mid) m.push_back(n[i++]);
        while(j<=r) m.push_back(n[j++]);
        for(i=0,j=l;i<m.size();i++,j++) n[j]=m[i];
    }
    int majorityElement(vector<int>& nums) {
        int st=nums.size()/2;
        merge_sort(nums,0,nums.size()-1);
        return nums[st];
    }
};

面试题 10.01. 合并排序的数组

class Solution {
public:
    void merge_sort(vector<int>&n,int l,int r) {
        if(l>=r) return;
        vector<int>m;
        int mid=l+r>>1;
        merge_sort(n,l,mid),merge_sort(n,mid+1,r);
        int i,j;
        for(i=l,j=mid+1;i<=mid&&j<=r;) {
            if(n[i]<n[j]) m.push_back(n[i++]);
            else m.push_back(n[j++]);
        }
        while(i<=mid) m.push_back(n[i++]);
        while(j<=r) m.push_back(n[j++]);
        for(i=0,j=l;i<m.size();i++,j++) n[j]=m[i];
    }
    void merge(vector<int>& A, int m, vector<int>& B, int n) {
        for(int i=0;i<n;i++) A[m+i]=B[i];
        merge_sort(A,0,A.size()-1);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习算法的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值