為了方便,使用一維陣列來分析。所謂矩陣轉置,行變列,列變行。在轉置的過程中,有的元素位置是不變的;對於變化位置的元素,要求o(1)空間完成,那麼這些位置的變化一定是有著規律的。
舉例,2×5的矩陣,a=;轉置後為at
=,探索下標變化:
0->0
1->2->4->8->7->5->1
3->6->3
9->9
這些下標的變化是一些環,如果我們能找到這個環,對環做移動處理,就可以o(1)完成了。
現在的問題是,我們如何知道乙個環是已經處理過的,仔細觀察,如果乙個環被處理過,那麼總能找到乙個它的後繼是小於它的。例如,處理了前三個環的時候,當嘗試找下標4打頭的環時,一直找4的後繼下標,會發現後繼1是小於4的,我們就知道4是存在於一條已經處理過的環,跳過。
接下來的問題是如何找到當前元素下標的前驅和後繼。先求下標i轉置前的下標,即i的前驅,對於m×n的矩陣,轉置後為n×m,則一維陣列的第i個元素表示的行列為(i/m, i%m),根據轉置原理,那麼這個元素在轉置前的m×n矩陣中所表示的行列為(i%m, i/m),那麼i在轉置前一維陣列中的位置為j=(i%m)×n+(i/m)。同理,下標i轉置後的位置j=(i%n)×m+(i/n)。
這樣,前驅後繼都可以求得,找到環就移動環的元素,如果已處理過則跳過,**如下 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
int pre(int index, int m, int n) // 求前驅
int next(int index, int m, int n) // 求後繼
void move(int * a, int i, int m, int n) // 處理環
a[cur] = curval;
}
void transpose(int *a, int m, int n) // 轉置
if(next == i)
}
}
簡單測試如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main()
;
for(int i = 0; i < 10; ++i)
printf("\n");
transpose(a,2,5);
for(int i = 0; i < 10; ++i)
printf("\n");
return 0;
}
O 1 空間內實現矩陣轉置
題目 將乙個mxn的矩陣儲存在乙個一維陣列中,程式設計實現矩陣的轉置。include include 題目 將乙個mxn的矩陣儲存在乙個一維陣列中,程式設計實現矩陣的轉置。詳細說明參考 求i前序,row為矩陣行數,col為矩陣列數 轉置後i在 i row,i row 則轉置前為 i row,i ro...
數字排序 o n 時間 o 1 空間
乙個時間複雜度為o n 空間複雜度為o 1 的排序演算法 收藏 乙個時間複雜度為o n 空間複雜度為o 1 的排序演算法 有n個大小不等的自然數 1 n 請將它們由小到大排序。要求程式演算法 時間複雜度為o n 空間複雜度為o 1 從這道題出題意圖來看,出題者主要是想考面試者的思維是否敏捷清醒 做事...
數字排序 o n 時間 o 1 空間
乙個時間複雜度為o n 空間複雜度為o 1 的排序演算法 收藏 乙個時間複雜度為o n 空間複雜度為o 1 的排序演算法 有n個大小不等的自然數 1 n 請將它們由小到大排序。要求程式演算法 時間複雜度為o n 空間複雜度為o 1 從這道題出題意圖來看,出題者主要是想考面試者的思維是否敏捷清醒 做事...