5
5
the image by 90 degrees. Can you do this in place?
6
6
"""
7
7
import unittest
8
- from typing import List , Callable
8
+ from typing import List
9
9
10
10
11
11
def rotate_matrix (matrix : List [List [int ]], N : int ) -> List [List [int ]]:
@@ -24,19 +24,45 @@ def rotate_matrix(matrix: List[List[int]], N: int) -> List[List[int]]:
24
24
return rotated
25
25
26
26
27
- def rotate_matrix_in_place (matrix : List [List [int ]], N : int ) -> List [List [int ]]:
27
+ def rotate_matrix_in_place (matrix : List [List [int ]], start_row : int , start_col : int , N : int ) -> List [List [int ]]:
28
28
"""
29
29
Does the same as rotate_matrix, but in place.
30
+ Runtime: O(N^2), asymptotic runtime depends on N. We make N^2 swaps.
31
+ Space Complexity: O(1), constant amount of temp variables that does not depend on N.
32
+ Note: I am assuming that compiler will optimize the tail recursion.
30
33
:param matrix: an NxN matrix
34
+ :param start_row: starting row index
35
+ :param start_col: starting col index
31
36
:param N: the size of the matrix (NxN)
32
- :return:
37
+ :return: the input matrix, but rotated
33
38
"""
34
- return matrix
39
+ num_rotations = 4
40
+ if N == 0 or N == 1 :
41
+ return matrix
42
+ col = start_col
43
+ while True :
44
+ rotated_row = start_row
45
+ rotated_col = col
46
+ temp_new = matrix [start_row ][col ]
47
+ for r in range (0 , num_rotations ):
48
+ temp = temp_new
49
+ # compute new rotated indices
50
+ prev_col = rotated_col
51
+ rotated_col = N - 1 - rotated_row + (start_row * 2 ) # offset to account for reduced N
52
+ rotated_row = prev_col
53
+ # store value at newly computed indices
54
+ temp_new = matrix [rotated_row ][rotated_col ]
55
+ matrix [rotated_row ][rotated_col ] = temp
56
+ if col - start_col >= N - 2 :
57
+ break
58
+ col = col + 1
59
+ return rotate_matrix_in_place (matrix , start_row + 1 , start_col + 1 , N - 2 )
35
60
36
61
37
62
class TestRotateMatrixFunction (unittest .TestCase ):
38
- def _run_tests (self , f : Callable [[List [List [int ]], int ], List [List [int ]]]):
39
- cases = [
63
+
64
+ def setUp (self ):
65
+ self .cases = [
40
66
(
41
67
[
42
68
[1 , 2 , 3 , 4 ],
@@ -73,14 +99,75 @@ def _run_tests(self, f: Callable[[List[List[int]], int], List[List[int]]]):
73
99
[
74
100
[1 ]
75
101
]
102
+ ),
103
+ (
104
+ [
105
+ [1 , 2 , 3 , 4 , 5 , 6 ],
106
+ [7 , 8 , 9 , 10 , 11 , 12 ],
107
+ [13 , 14 , 15 , 16 , 17 , 18 ],
108
+ [19 , 20 , 21 , 22 , 23 , 24 ],
109
+ [25 , 26 , 27 , 28 , 29 , 30 ],
110
+ [31 , 32 , 33 , 34 , 35 , 36 ]
111
+ ],
112
+ 6 ,
113
+ [
114
+ [31 , 25 , 19 , 13 , 7 , 1 ],
115
+ [32 , 26 , 20 , 14 , 8 , 2 ],
116
+ [33 , 27 , 21 , 15 , 9 , 3 ],
117
+ [34 , 28 , 22 , 16 , 10 , 4 ],
118
+ [35 , 29 , 23 , 17 , 11 , 5 ],
119
+ [36 , 30 , 24 , 18 , 12 , 6 ]
120
+ ]
121
+ ),
122
+ (
123
+ [
124
+ [1 , 2 , 3 , 4 , 5 ],
125
+ [6 , 7 , 8 , 9 , 10 ],
126
+ [11 , 12 , 13 , 14 , 15 ],
127
+ [16 , 17 , 18 , 19 , 20 ],
128
+ [21 , 22 , 23 , 24 , 25 ]
129
+ ],
130
+ 5 ,
131
+ [
132
+ [21 , 16 , 11 , 6 , 1 ],
133
+ [22 , 17 , 12 , 7 , 2 ],
134
+ [23 , 18 , 13 , 8 , 3 ],
135
+ [24 , 19 , 14 , 9 , 4 ],
136
+ [25 , 20 , 15 , 10 , 5 ]
137
+ ]
138
+ ),
139
+ (
140
+ [
141
+ [1 , 2 , 3 , 4 , 5 , 6 , 7 ],
142
+ [8 , 9 , 10 , 11 , 12 , 13 , 14 ],
143
+ [15 , 16 , 17 , 18 , 19 , 20 , 21 ],
144
+ [22 , 23 , 24 , 25 , 26 , 27 , 28 ],
145
+ [29 , 30 , 31 , 32 , 33 , 34 , 35 ],
146
+ [36 , 37 , 38 , 39 , 40 , 41 , 42 ],
147
+ [43 , 44 , 45 , 46 , 47 , 48 , 49 ]
148
+ ],
149
+ 7 ,
150
+ [
151
+ [43 , 36 , 29 , 22 , 15 , 8 , 1 ],
152
+ [44 , 37 , 30 , 23 , 16 , 9 , 2 ],
153
+ [45 , 38 , 31 , 24 , 17 , 10 , 3 ],
154
+ [46 , 39 , 32 , 25 , 18 , 11 , 4 ],
155
+ [47 , 40 , 33 , 26 , 19 , 12 , 5 ],
156
+ [48 , 41 , 34 , 27 , 20 , 13 , 6 ],
157
+ [49 , 42 , 35 , 28 , 21 , 14 , 7 ]
158
+ ]
76
159
)
77
160
]
78
- for matrix , N , expected in cases :
79
- self .assertEqual (f (matrix , N ), expected , msg = (matrix , N , expected ))
80
161
81
162
def test_rotate_matrix (self ):
82
- self ._run_tests (rotate_matrix )
83
- # self._run_tests(rotate_matrix_in_place)
163
+ for matrix , N , expected in self .cases :
164
+ self .assertEqual (rotate_matrix (matrix , N ), expected , msg = (matrix , N , expected ))
165
+
166
+ def test_rotate_matrix_in_place (self ):
167
+ start_row = 0
168
+ start_col = 0
169
+ for matrix , N , expected in self .cases :
170
+ self .assertEqual (rotate_matrix_in_place (matrix , start_row , start_col , N ), expected , msg = (matrix , N , expected ))
84
171
85
172
86
173
if __name__ == '__main__' :
0 commit comments