您的位置:首页 > 其它

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

2017-01-15 11:51 274 查看
思路:

* 每个元素转置前后会形成一个环(一个数字有多个环)

* 利用环来移动元素达到转置

* 关键:

* 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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: