简化题意

给出两个长度分别为n,m n, m 的序列(每一个序列都有序),请将它们合并之后排序。

分析

此题是归并排序的前奏,强烈建议搭配课程使用。

我们已经知道,快速排序的复杂度为O(nlogn)O(n\log n),但此题数据很强,数据范围为n<107n < 10^7,用O(nlogn)O(n\log n)的复杂度在200万到500万的数据时就会爆炸。

而为了降低时间复杂度,这一题我们可以用这个方法:

举个例子:序列1:1 2 5 序列2:1 3 4

第一次比较:a[0] = 1 b[0] = 1,1=1,将a[0]放入结果序列中

第二次比较:a[1] = 2 b[0] = 1,2>1,将b[0]放入结果序列中

第三次比较:a[1] = 2 b[1] = 3,2<3,将a[1]放入结果序列中

第四次比较:a[2] = 5,b[1] = 3,5>3,将b[1]放入结果序列中

第五次比较:a[2] = 5,b[2] = 4,将b[2]放入结果序列中。

这里友情给出合并序列的一部分代码:

int ind1 = 0, ind2 = 0, ind3 = 0; // ind1 是 a 数组的比较下标,ind2 是 b 数组的比较下标,ind3 是 c 数组的存储下标。
while(ind1 < n && ind2 < m){ // 当两个数组均未被比较完填入时
	if(a[ind1] <= b[ind2]){ // a 数组对应项小于或等于 b 数组对应项,取等号是为保证稳定性
		c[ind3++] = a[ind1++]; // 记录
	}
	else{
		c[ind3++] = b[ind2++]; // 记录
	}
}

知识彩蛋1号:各种时间复杂度的超时输入规模(以1亿为界限,相当于时限1s;按复杂度从小到大排序)

复杂度 代入8后的值 代入16后的值 超时输入规模 算法举例
O(1)O(1) 1 永远不会超时 -
O(logn)O(\log n) 3 4 2的1亿次方
O(n)O(n) 8 16 1亿 欧拉筛
O(nlogn)O(n\log n) 24 64 200万-500万 埃氏筛、快排
O(n2)O(n^2) 64 256 1万 选择、冒泡
O(n3)O(n^3) 512 4096 464与465之间 -
O(2n)O(2^n) 256 65536 26与27之间
O(3n)O(3^n) 6561 43046721 16与17之间
O(n!)O(n!) 40320 一个13位数 11与12之间

如果你用到了数据范围超过你所计算的复杂度超时输入规模的方法,请想另一种方法或尝试优化;不建议使用O(n3)O(n^3)及以上的复杂度,建议最多只使用双重循环。