# 498. Diagonal Traverse #### Difficulty: Medium link: https://leetcode.com/problems/diagonal-traverse/ ### 1. Simulation #### $O(MN)$ runtime, $O(1)$ space 這題讓我想到之前解過一題光學折射的題目 [Mirror Reflection](https://leetcode.com/problems/mirror-reflection/),運用類似的概念,設定兩個 index 分別為 i 和 j 來 traverse matrix,以及他們各自要前進的方向 di 和 dj,當碰到 matrix 的四個邊界時,會對應到不同的反射方式。值得注意的是,需要優先考慮撞到右方或下方邊界的情況。 ##### python ```python= class Solution: def findDiagonalOrder(self, matrix: List[List[int]]) -> List[int]: M = len(matrix) if M == 0: return [] N = len(matrix[0]) ans = [] i , j = 0, 0 di, dj = -1, 1 while True: ans.append(matrix[i][j]) if i == M-1 and j == N-1: break if i+di > M-1: di = -di dj = -dj j += dj elif j+dj > N-1: di = -di dj = -dj i += di elif i+di < 0: j += dj di = -di dj = -dj elif j+dj < 0: i += di di = -di dj = -dj else: i += di j += dj return ans ``` <font color="#00AB5F ">Accepted</font> Runtime: **188 ms**, faster than **80.57%** of Python3 online submissions for Diagonal Traverse. Memory Usage: **16.8 MB**, less than **37.68%** of Python3 online submissions for Diagonal Traverse. ### 2. Simulation #### $O(MN)$ runtime, $O(MN)$ space 上面解法的缺點在於程式碼易讀性低,在討論區看到一個比較直觀的寫法。 利用了每個 diagonal 的兩個 index 總和固定的特性,先將每個 diagonal 的元素存在一個 dict 裡面,回傳前再對偶數 digonal 做 reverse。 ```python= class Solution: def findDiagonalOrder(self, matrix: List[List[int]]) -> List[int]: d={} for i in range(len(matrix)): for j in range(len(matrix[i])): if i + j not in d: d[i+j] = [] d[i+j].append(matrix[i][j]) ans= [] for key, value in d.items(): if key % 2 == 0: ans += reversed(value) else: ans += value return ans ``` <font color="#00AB5F ">Accepted</font> Runtime: **192 ms**, faster than **68.01%** of Python3 online submissions for Diagonal Traverse. Memory Usage: **17.2 MB**, less than **18.04%** of Python3 online submissions for Diagonal Traverse. ###### tags: `leetcode`