forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cyclically-rotating-a-grid.py
74 lines (66 loc) · 2.22 KB
/
cyclically-rotating-a-grid.py
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# Time: O(m * n)
# Space: O(1)
import fractions
# inplace rotation
class Solution(object):
def rotateGrid(self, grid, k):
"""
:type grid: List[List[int]]
:type k: int
:rtype: List[List[int]]
"""
def get_index(m, n, l):
if l < m-1:
return l, 0
if l < (m-1)+(n-1):
return m-1, l-(m-1)
if l < (m-1)+(n-1)+(m-1):
return (m-1)-(l-((m-1)+(n-1))), n-1
return 0, (n-1)-(l-((m-1)+(n-1)+(m-1)))
m, n = len(grid), len(grid[0])
for i in xrange(min(m, n)//2):
total = 2*((m-1)+(n-1))
nk = k%total
num_cycles = fractions.gcd(total, nk)
cycle_len = total//num_cycles
for offset in xrange(num_cycles):
r, c = get_index(m, n, offset)
for j in xrange(1, cycle_len):
nr, nc = get_index(m, n, (offset+j*nk)%total)
grid[i+nr][i+nc], grid[i+r][i+c] = grid[i+r][i+c], grid[i+nr][i+nc]
m, n = m-2, n-2
return grid
# Time: O(m * n)
# Space: O(1)
# inplace rotation
class Solution2(object):
def rotateGrid(self, grid, k):
"""
:type grid: List[List[int]]
:type k: int
:rtype: List[List[int]]
"""
def get_index(m, n, l):
if l < m-1:
return l, 0
if l < (m-1)+(n-1):
return m-1, l-(m-1)
if l < (m-1)+(n-1)+(m-1):
return (m-1)-(l-((m-1)+(n-1))), n-1
return 0, (n-1)-(l-((m-1)+(n-1)+(m-1)))
def reverse(grid, m, n, i, left, right):
while left < right:
lr, lc = get_index(m, n, left)
rr, rc = get_index(m, n, right)
grid[i+lr][i+lc], grid[i+rr][i+rc] = grid[i+rr][i+rc], grid[i+lr][i+lc]
left += 1
right -= 1
m, n = len(grid), len(grid[0])
for i in xrange(min(m, n)//2):
total = 2*((m-1)+(n-1))
nk = k%total
reverse(grid, m, n, i, 0, total-1)
reverse(grid, m, n, i, 0, nk-1)
reverse(grid, m, n, i, nk, total-1)
m, n = m-2, n-2
return grid