归并排序:先将数组一分为二,将左边部分排序(同样将其一分为二),再将右边部分排序,最后逐层归并。(分治策略)(稳定排序)。

算法稳定性 -- 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!

先排序的时间复杂度为log(n);

后归并的时间复杂度为n;

总的时间复杂度nlog(n)。

 

1)自顶向下归并排序的代码:需要一个和待排序数组相同的空间,故将arr[]拷贝一份给aux[]

//将arr[l...mid]和 arr[mid+1...r]两部分进行归并
template<typename T>
void merge(T arr[], int l, int mid, int r){
//需要一个临时的和arr同样大小的空间
T aux[r-l+];
for(int i=l;i<=r;i++)
//将arr复制给aus,aus下标从0开始,而arr下标从l开始
aux[i-l] = arr[i];
//初始化,i指向左半部分的起始索引位置l;j指向右半部分起始索引位置mid+1
int i = l, j = mid+;
for(int k=l;k<=r;k++){
//逐步比较左部分的第i个元素和右部分的第j个元素的大小
//首先判断下标i和j的合法性
if(i>mid){
//左边已经遍历完,但右边还有
arr[k] = aux[j-l];
j++
}
else if(j>r){
//右边已经遍历完,将左边的元素给arr
arr[k] = aux[i-l];
i++;
}
else if(aux[i-l]<aux[j-l]){
arr[k] = aux[i-l];
i++;
}
else{
arr[k] = aux[j-l];
j++;
}
}
} //递归使用归并排序,对arr[l...r]的范围进行排序
template<typename T>
void mergeSort(T arr[], int l, int r){
if(l>=r)
return;
int mid = (l+r)/;
mergeSort(arr, l, mid);
mergeSort(arr, mid+,r);
//优化:只有当 mid>mid+1 时才需要对左右两边进行排序
//因为左边或右边本身是有序的,如果 mid<=mid+1 则不需要对其归并排序了
if(arr[mid] > arr[mid+])
merge(arr,l,mid,r);
}

当数组中的元素足够少时,可以将递归出口改为插入排序,虽然插入排序的时间复杂度是O(n),但是可以提高效率。

2)自底向上归并排序:

template<typename T>      //泛型
void mergeSortBU(T arr[], int n){
//自底向上归并
//对merge的元素个数进行遍历:1,2,4,8以此类推
for(int sz= ; sz<=n ; sz+=sz ){
for(int i=; i+sz<n; i+=sz+sz)
//对arr[i...i+sz-1]和arr[i+sz...i+2*sz-1]进行归并
merge(arr, i, i+sz-, min(i+sz+sz-, n-));
}
}

注意:nums1和nums2 是有序的,m代表nums1元素的个数。

这里的解题思想是归并排序的merge()函数的思想,先开辟一个与nums1相同大小和值的空间aux,再将其与nums2逐一对比,用小的来替换nums1的值。

class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { if (m <= && n <= ) return;
//int aux[m];
vector<int> aux(m);
for(int i=;i<m;i++){
//将nums1的值拷贝给aux
aux[i] = nums1[i];
} int i=,j=;
for(int k=;k<nums1.size();k++){
if(i>m-){
//aux数组超界
nums1[k] = nums2[j];
j++;
}
else if(j>n-){
nums1[k] = aux[i];
i++;
}
else if(nums2[j]<aux[i]){
nums1[k] = nums2[j];
j++;
}
else{
nums1[k] = aux[i];
i++;
} }
}
};

解法二:从两个数组的末尾开始比较大小,从下标为m+n-1开始存放,将大的存放在nums1的末尾。如果最后剩下的是nums1,则不需要移动;若是nums2中的元素则需要放在nums1的相应位置。

class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { if (m <= && n <= ) return; int count = m+n-;
--m, --n; //m和n是长度,所以要减1变成下标
while(m>= && n>=){
if(nums1[m] >nums2[n])
nums1[count--] = nums1[m--];
else
nums1[count--] = nums2[n--];
}
while(n>=){
//当m已经全部遍历完,n还剩下
nums1[count--] = nums2[n--];
}
}
};

leetcode 88 Merge Sorted Array 归并排序的更多相关文章

  1. Leetcode#88. Merge Sorted Array(合并两个有序数组)

    题目描述 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 m ...

  2. [LeetCode] 88. Merge Sorted Array 混合插入有序数组

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: T ...

  3. LeetCode 88. Merge Sorted Array(合并有序数组)

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note:Yo ...

  4. leetCode 88.Merge Sorted Array (合并排序数组) 解题思路和方法

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: Y ...

  5. [LeetCode] 88. Merge Sorted Array 合并有序数组

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: T ...

  6. LeetCode 88 Merge Sorted Array

    Problem: Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array ...

  7. Leetcode 88. Merge Sorted Array(easy)

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note:Yo ...

  8. [leetcode]88. Merge Sorted Array归并有序数组

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: T ...

  9. Leetcode 88 Merge Sorted Array STL

    合并有序数组 时间复杂度O(m+n) 该算法来自各种算法与数据结构书,写得已经烂得不能再烂了,这个应该是最短的代码了吧,不知如何归类 class Solution { public: void mer ...

随机推荐

  1. Angular25 组件的生命周期钩子

    1 生命周期钩子概述 组件共有9个生命周期钩子 1.1 生命周期的执行顺序 技巧01:测试时父组件传递对子组件的输入属性进行初始化操作 import { Component, Input, Simpl ...

  2. 打印vector内容

    <span style="font-size:14px;">#include <iostream> #include <vector> #inc ...

  3. 数字图像处理实验(12):PROJECT 05-03,Periodic Noise Reduction Using a Notch Filter 标签: 图像处理MATLAB 2017-0

    实验要求: Objective: To understand the principle of the notch filter and its periodic noise reducing abi ...

  4. jQuery--加一行减一行

    效果: 知识点: 克隆--clone() 追加--append() 移除--remove() 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2 ...

  5. 不用EL表达式---实现product页面显示

    产品页面显示 静态页面如下: <%@ page language="java" contentType="text/html; charset=UTF-8" ...

  6. 使用 Vue.component

    引入 vue.js. HTML <div id="app"></div> CSS .greeting { padding: 3rem 1.5rem; bac ...

  7. linux内存监控 free

    free 命令详解: 执行命令后总共四行. 第一行: 列头 第二行: total 内存总数: 32881776 used 已经使用的内存数: 8324796 free 空闲的内存数: 24556980 ...

  8. quartz 使用配置文件配置线程数

    quartz默认的线程数是10个,如果我们要修改这个线程数需要做一个配置文件,在配置文件内修改线程. 一共需要2个操作: 1.找到quartz的XML配置文件,设置加载配置文件(配置文件存放在weba ...

  9. HTML5+CSS3从入门到精通随书光盘 ISO 镜像视频教程​

    HTML5+CSS3从入门到精通(清华社“视频大讲堂”大系)通过基础知识+中小实例+综合案例的方式,讲述了用HTML5+ CSS3设计构建网站的必备知识,相对于权威指南.高级程序设计.开发指南同类图书 ...

  10. 国外物联网平台(6):Electric Imp

    国外物联网平台(6)——Electric Imp 马智 公司背景 Electric Imp成立于2011年,公司设立在美国加利福尼亚州洛斯阿尔托斯和英国剑桥 公司投资者包括:富士康技术集团.PTI创投 ...