O(1)空间内实现矩阵转置

本文探讨如何在常数空间内高效地完成矩阵转置操作,通过算法解析,阐述了在不额外占用大量内存的情况下,实现矩阵转置的关键步骤和思考过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:
 * 每个元素转置前后会形成一个环(一个数字有多个环)
 * 利用环来移动元素达到转置
 * 关键:
 * 1.得到元素下标的前驱后继,
 * 2.判断环是否已走过(意味属于一个环的元素一次转置完成)
 * 解决:
 * 1.从一维下标转二维坐标得到转置后的二维坐标再换回一维坐标
 * 如:M*N矩阵
 * 假设转置前某个元素的数组下标为i,则它所在行列为(i/N, i%N),
 * 转置后所在行列则为(i%N, i/N),可计算转置后数组下标为(i%N)*M+i/N,
 * 此为i的后继。假设转置后某个元素的数组下标为i,则它所在行列为(i/M, i%M),
 * 则转置前所在行列为(i%M, i/M),可计算此时下标为(i%M)*N+i/M,此为i的前驱。
 *

 * 2.从一个下标开始直到回到自身没有出现比它小的下标,则环没走过

#include <iostream>
using namespace std;

#define M 4
#define N 2

int getPrev(int i, int m, int n) {
	return (i % M) * N + i / M;
}

int getNext(int i, int m, int n) {
	return (i % N) * M + i / N;
}

void moveData(int* arr, int i) {
	int cur = i;
	int temp = arr[i];
	int prev = getPrev(i, M, N);
	while (prev != i) {
		arr[cur] = arr[prev];
		cur = prev;
		prev = getPrev(cur, M, N);
	}
	arr[cur] = temp;
}

void transfer(int* arr, int m, int n) {
	for (int i = 0; i < m * n; ++i) {
		int next = getNext(i, m, n);
		while (i < next) {
			next = getNext(next, m, n);
		}
		//环未走过
		if (i == next) {
			moveData(arr, i);
		}
	}
}

void printMatrix(int* matrix, int m, int n) {
	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < n; ++j) {
			cout << matrix[i * n + j] << " ";
		}
		cout << endl;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值