矩陣轉置 O 1 空間

2021-07-04 23:52:46 字數 2572 閱讀 1881



為了方便,使用一維陣列來分析。所謂矩陣轉置,行變列,列變行。在轉置的過程中,有的元素位置是不變的;對於變化位置的元素,要求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 從這道題出題意圖來看,出題者主要是想考面試者的思維是否敏捷清醒 做事...