「学习笔记」归并排序的空间优化

归并排序的时间复杂度为 Onlogn,一般的空间复杂度为 On,但事实上我们可以将这个空间复杂度优化到 O1


对于 aiaj 这两个元素,我们要把他们都存到 ak 这个位置里,我们可以这样操作
找一个比 max(ai,aj) 大的数 maxx,让 ak=ak+max(ai,aj)×maxx
这样,我们可以通过这个式子来表示出原本的 akmax(ai,aj)

ak=akmodmaxxaj=akmaxx

这样,我们就不必再开一个和原数组长度一样的辅助数组了,但是由于会多次取模,所以时间上会比空间复杂度为 On 的归并排序慢


代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mid ((l + r) >> 1)

const int N = 1e5 + 5;

int n;
ll _max;
ll a[N];

void mergearray(int l, int mi, int r, ll maxn) {
	int i = l, j = mi + 1, k = l;
	while (i <= mi && j <= r) {
		if (a[i] % maxn <= a[j] % maxn) {
			// a[i] % maxn 与 a[j] % maxn 是 a[i] 与 a[j] 原本的值
			a[k] = a[k] + (a[i] % maxn) * maxn;
			++ k, ++ i;
		}
		else {
			a[k] = a[k] + (a[j] % maxn) * maxn;
			++ k, ++ j;
		}
	}
	while (i <= mi) {
		a[k] = a[k] + (a[i] % maxn) * maxn;
		++ k, ++ i;
	}
	while (j <= r) {
		a[k] = a[k] + (a[j] % maxn) * maxn;
		++ k, ++ j;
	}
	for (int i = l; i <= r; ++ i) {
		a[i] /= maxn;
	}
}

void mergesort(int l, int r, ll maxn) {
	if (l < r) {
		mergesort(l, mid, maxn);
		mergesort(mid + 1, r, maxn);
		mergearray(l, mid, r, maxn);
	}
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i) {
		scanf("%lld", &a[i]);
		_max = max(_max, a[i]);
	}
	_max += 1;
	mergesort(1, n, _max);
	for (int i = 1; i <= n; ++ i) {
		printf("%d%c", a[i], " \n"[i == n]);
	}
	return 0;
}

作者:yifan0305

出处:https://www.cnblogs.com/yifan0305/p/17280154.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载时还请标明出处哟!

posted @   yi_fan0305  阅读(111)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示