矩阵原地转置
来源:互联网 发布:学编程用什么笔记本 编辑:程序博客网 时间:2024/05/16 10:47
一,问题描述
微软面试题:将一个MxN的矩阵存储在一个一维数组中,编程实现矩阵的转置。
要求:空间复杂度为O(1)
二,思路分析
下面以一个4x2的矩阵A={1,2,3,4,5,6,7,8}进行分析,转置过程如下图:
图中右下角的红色数字表示在一维数组中的下标。矩阵的转置其实就是数组中元素的移动,具体的移动过程如下图:
我们发现,这些移动的元素的下标是一个个环,下标1的元素移动到4,下标4的元素移动到2,下标2的元素移动到1。在编写程序的时候,我们需要解决两个问题:第一个是如何判定环是否重复(已处理过);第二个是如何计算当前元素下标的前驱与后继。
第一个问题:如何判断环是重复已处理过的?因为我们遍历整个数组时下标是从小到大的,所以如果是第一次遍历该环,则第一个下标肯定是这个环中最小的。如果一个环被处理过,那么总能找到一个它的后继是小于它的。从上图可以明显看出来。
第二个问题:如何计算当前元素下标的前驱与后继?假设转置前某个元素的数组下标为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的前驱。
三,代码实现
/************************************************************************* > File Name: matrix_transpose.cpp > Author: SongLee > E-mail: lisong.shine@qq.com > Created Time: 2014年06月06日 星期五 14时26分15秒 > Personal Blog: http://songlee24.github.io ************************************************************************/#include<iostream>using namespace std;/* 后继 */int getNext(int i, int m, int n){ return (i%n)*m + i/n;}/* 前驱 */int getPre(int i, int m, int n){ return (i%m)*n + i/m;}/* 处理以下标i为起点的环 */void movedata(int *mtx, int i, int m, int n){ int temp = mtx[i]; // 暂存 int cur = i; // 当前下标 int pre = getPre(cur, m, n); while(pre != i) { mtx[cur] = mtx[pre]; cur = pre; pre = getPre(cur, m, n); } mtx[cur] = temp;}/* 转置,即循环处理所有环 */void transpose(int *mtx, int m, int n){ for(int i=0; i<m*n; ++i) { int next = getNext(i, m, n); while(next > i) // 若存在后继小于i说明重复 next = getNext(next, m, n); if(next == i) // 处理当前环 movedata(mtx, i, m, n); }}/* 输出矩阵 */void print(int *mtx, int m, int n){ for(int i=0; i<m*n; ++i) { if((i+1)%n == 0) cout << mtx[i] << "\n"; else cout << mtx[i] << " "; }}/* 测试 */int main(){ int matrix[4*2] = {1,2,3,4,5,6,7,8}; cout << "Before matrix transposition:" << endl; print(matrix, 4, 2); transpose(matrix, 4, 2); cout << "After matrix transposition:" << endl; print(matrix, 2, 4); return 0;}
运行结果:
参考:http://www.ahathinking.com/archives/217.html
0 0
- 矩阵原地转置
- 矩阵原地转置
- 矩阵的原地转置
- 矩阵原地转置、旋转
- 矩阵原地转置算法
- 原地矩阵转置算法实现
- C++实现矩阵原地转置算法
- 矩阵--原地转置--面试题
- 方阵原地转置
- 矩阵原地转置,空间复杂度为O(1)(暂时先保存下来)
- 原地矩阵旋转
- 二维矩阵原地转换
- 原地旋转矩阵
- 原地转置单向链表
- C++数组原地转置代码
- 数组原地逆置
- 单链表原地置逆
- 单链表原地逆置
- LeetCode OJ平台上Binary Tree Inorder Traversal题目使用java堆栈方式实现
- 摆脱科技僵尸,回归生龙活虎
- Jboss7+HornetQ(持久订阅)
- 仿百度输入框自动匹配功能的JS代码
- 处理驾校学员系统编号重复的问题
- 矩阵原地转置
- Test
- 补充个python监控小函数,证书过期发送警告
- 如何修改myeclipse中web项目的工作路径或默认路径
- [LeetCode] Palindrome Partitioning II [12]
- lynxos
- 再访俄罗斯地下世界
- 修改CMD命令回显语言 中文->English
- Tomcat8 安装和运行