假设A[1...n]是一个有n个不同元素的数组,若i<j且A[i]>A[j],则对偶(i,j)称为A的一个逆序对。
求出数组[2, 3, 8, 6, 1]的5个逆序对。
按照定义实现的算法,时间复杂度O(n^2):
代码如下:
var a = [2, 3, 8, 6, 1];
var p = reversePairs(a);
console.log('数组:', a.join(','));
console.log('逆序对个数:', p.length);
console.log('逆序对:', p);
function reversePairs(a){
var r = [];
var len = a.length;
for(var i = 0; i < len - 1; i++){
for(var j = i + 1; j < len; j++){
if(a[i] > a[j]){
//r.push([i, j]);
r.push([a[i],a[j]]);
}
}
}
return r;
}使用归并排序,可以使时间复杂度降为O(nlgn):
代码如下:
var a = [2, 3, 8, 6, 1];
var p = [];
mergeReversePairs(a, 0, a.length, p);
console.log('数组:', a.join(','));
console.log('逆序对个数:', p.length);
console.log('逆序对:', p);
function mergeReversePairs(a, p, r, ){
if(p < r - 1){
var q = Math.floor((p + r) / 2);
mergeReversePairs(a, p, q, );
mergeReversePairs(a, q, r, );
merge(a, p, q, r, );
}
return b;
}
function merge(a, p, q, r, ){
var n1 = q - p;
var n2 = r - q;
var L = [];
var R = [];
for(var i = 0; i < n1; i++){
L[i] = a[p + i];
}
for(var j = 0; j < n2; j++){
R[j] = a[q + j];
}
L[n1] = Infinity;
R[n2] = Infinity;
var i = 0;
var j = 0;
for(var k = p; k < r; k++){
if(L[i] < R[j]){
a[k] = L[i];
i++;
}
else {
a[k] = R[j];
j++;
}
}
}其实就是用归并排序算法给数组排了序,排序过程中记录了一下逆序对,注意粗体部分。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。