-
Notifications
You must be signed in to change notification settings - Fork 31
/
enumerateDiagnal.py
132 lines (118 loc) · 3.93 KB
/
enumerateDiagnal.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# 对角线遍历/遍历对角线
from typing import Generator, List, Tuple
def enumerateDiagnal(
row: int, col: int, direction=0, upToDown=True
) -> Generator[List[Tuple[int, int]], None, None]:
"""
对角线遍历二维矩阵.左上角为(0,0).
Args:
- direction (int): 遍历方向.
- `0: ↘`, 从左上到右下. 同一条对角线上 `r-c` 为定值.
- `1: ↖`, 从右下到左上. 同一条对角线上 `r-c` 为定值.
- `2: ↙`, 从右上到左下. 同一条对角线上 `r+c` 为定值.
- `3: ↗`, 从左下到右上. 同一条对角线上 `r+c` 为定值.
- upToDown (bool): 是否从上到下遍历. 默认为True.
Returns:
Generator[List[Tuple[int, int]], None, None]: 每个对角线上的元素坐标(r,c)的列表.
"""
if direction not in (0, 1, 2, 3):
raise ValueError("direction must be in (0, 1, 2, 3)")
if direction == 0:
for key in range(-col + 1, row) if upToDown else range(row - 1, -col, -1):
r = 0 if key < 0 else key
c = r - key
cur = []
while r < row and c < col:
cur.append((r, c))
r += 1
c += 1
if cur:
yield cur
elif direction == 1:
for key in range(-col + 1, row) if upToDown else range(row - 1, -col, -1):
r = row - 1 if key > row - col else key + col - 1
c = r - key
cur = []
while r >= 0 and c >= 0:
cur.append((r, c))
r -= 1
c -= 1
if cur:
yield cur
elif direction == 2:
for key in range(row + col - 1) if upToDown else range(row + col - 2, -1, -1):
r = 0 if key < col else key - col + 1
c = key - r
cur = []
while r < row and c >= 0:
cur.append((r, c))
r += 1
c -= 1
if cur:
yield cur
elif direction == 3:
for key in range(row + col - 1) if upToDown else range(row + col - 2, -1, -1):
r = row - 1 if key >= row else key
c = key - r
cur = []
while r >= 0 and c < col:
cur.append((r, c))
r -= 1
c += 1
if cur:
yield cur
if __name__ == "__main__":
mat = [[1, 2, 3], [4, 5, 6]]
row, col = len(mat), len(mat[0])
assert list(enumerateDiagnal(row, col)) == [
[(0, 2)],
[(0, 1), (1, 2)],
[(0, 0), (1, 1)],
[(1, 0)],
]
assert list(enumerateDiagnal(row, col, 1)) == [
[(0, 2)],
[(1, 2), (0, 1)],
[(1, 1), (0, 0)],
[(1, 0)],
]
assert list(enumerateDiagnal(row, col, 2)) == [
[(0, 0)],
[(0, 1), (1, 0)],
[(0, 2), (1, 1)],
[(1, 2)],
]
assert list(enumerateDiagnal(row, col, 3)) == [
[(0, 0)],
[(1, 0), (0, 1)],
[(1, 1), (0, 2)],
[(1, 2)],
]
mat = [list(col[::-1]) for col in zip(*mat)]
row, col = len(mat), len(mat[0])
assert list(enumerateDiagnal(row, col)) == [
[(0, 1)],
[(0, 0), (1, 1)],
[(1, 0), (2, 1)],
[(2, 0)],
]
assert list(enumerateDiagnal(row, col, 1)) == [
[(0, 1)],
[(1, 1), (0, 0)],
[(2, 1), (1, 0)],
[(2, 0)],
]
assert list(enumerateDiagnal(row, col, 2)) == [
[(0, 0)],
[(0, 1), (1, 0)],
[(1, 1), (2, 0)],
[(2, 1)],
]
assert list(enumerateDiagnal(row, col, 3)) == [
[(0, 0)],
[(1, 0), (0, 1)],
[(2, 0), (1, 1)],
[(2, 1)],
]
print(*enumerateDiagnal(row, col, upToDown=False), sep="\n")
print(*enumerateDiagnal(row, col, upToDown=False), sep="\n")