[英]A BFS solution to Diagonally traverse a two dimensional array
我正在努力解決對角線遍歷問題- LeetCode
給定一個由 M x N 個元素(M 行,N 列)組成的矩陣,按對角線順序返回矩陣的所有元素,如下圖所示。
例子:
Input: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] Output: [1,2,4,7,5,3,6,8,9] Explanation:
筆記:
給定矩陣的元素總數不會超過 10,000。
可以將問題視為 bfs 從根 (0, 0) 遍歷到目的地 (rows, cols)
看了所有的投稿和討論,找到了一個比較簡潔的解決方案
class Solution:
def findDiagonalOrder(self, matrix: 'List[List[int]]') -> 'List[int]':
if len(matrix) == 0:
return []
r, c = 0, 0
rows, cols = len(matrix), len(matrix[0])
res = []
for _ in range(rows * cols):
res.append(matrix[r][c])
if (r + c) % 2 == 0:
if c == cols - 1: #column boundary
r += 1
elif r == 0: #
c += 1
else: #move up
r -= 1
c += 1
else:
if r == rows - 1: #row boundary
c += 1
elif c == 0:
r += 1
else:#move down
r += 1
c -= 1
return res
我有一種感覺,這樣的解決方案還不夠好,因為使用多個條件檢查的勞動力太多。
這種問題模式可能有一個通用的解決方案,以后可以用它來以最小的努力解決對角線遍歷問題。
問題是從 (0, 0) 到 (4, 4)
那些角色:
1. 對角線上每個節點的總和等於步數
2. 可能有一個關系公式可以從 root(0,0) 和上一層產生下一層的所有節點。
我的解決方案:
import unittest
import logging
logging.basicConfig(level=logging.DEBUG, format="%(levelname)s %(message)s")
class Solution:
def findDiagonalOrder(self, matrix: 'List[List[int]]') -> 'List[int]':
from collections import deque
#root is (0, 0)
#destination is (rows, cols)
r, c = 0, 0
root = (r, c)
rows, cols = len(matrix), len(matrix[0])
step = 0
queue = deque([root])
res = []
while queue and r < rows and c < cols:
step += 1
size = len(queue)
for _ in range(size):
r, c = queue.popleft()
res.append(matrix[r][c])
#collect the next nodes
if r == 0 and c == 0:
c = step #(0, 1) determin the direction of the first step
queue.append((r,c))
logging.debug(f"queue: {queue}")
logging.debug(f"step: {step}, r:{r}, c: {c}")
if c == 0:
level = [(step-i, i) for i in range(step)]
elif r == 0:
level = [(i, step-i) for i in range(step)]
queue += level
logging.debug(f"queue: {queue}")
#raise Exception
return res
class MyCase(unittest.TestCase):
def setUp(self):
self.solution = Solution()
def test_a(self):
matrix = [
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
answer = [1,2,4,7,5,3,6,8,9]
check = self.solution.findDiagonalOrder(matrix)
self.assertEqual(answer, check)
unittest.main()
然而,它停在
DEBUG queue: deque([(0, 2), (1, 1)])
DEBUG queue: deque([(0, 2), (1, 1)])
DEBUG queue: deque([(0, 2), (1, 1)])
DEBUG queue: deque([(0, 2), (1, 1)])
^CDEBUG queue: deque([(0, 2), (1, 1)])
Traceback (most recent call last):
我沒能寫出一個好的關系公式來生成下一級別的節點。
你能提供任何提示嗎?
我不確定這是否能回答你的問題,但如果我的方法對你來說足夠簡潔明了,我可以分享我的方法。
代碼是用 C++ 編寫的,但您可以理解。
class Solution {
public:
vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
vector<int> result;
int n = matrix.size();
if(n == 0) return result;
int m = matrix[0].size();
if(m == 0) return result;
result.resize(m * n);
int row = 0, col = 0, d = 0;
int dir[2][2] = {
{-1, 1},
{1, -1}
};
for (int i = 0; i < m * n; i++) {
result[i] = matrix[row][col];
row += dir[d][0];
col += dir[d][1];
if (row >= n) { row = n - 1; col += 2; d = 1 - d; }
if (col >= m) { col = m - 1; row += 2; d = 1 - d; }
if (row < 0) { row = 0; d = 1 - d;}
if (col < 0) { col = 0; d = 1 - d;}
}
return result;
}
};
遍歷方陣的解法
class Solution:
def findDiagonalOrder(self, matrix: 'List[List[int]]') -> 'List[int]':
from collections import deque
if(len(matrix) == 0 or len(matrix[0]) == 0):
return []
if(len(matrix) == 1):
return matrix[0]
res = []
if(len(matrix[0]) == 1):
for row in matrix:
res+=row
return res
r, c = 0, 0
root = (r, c)
rows, cols = len(matrix), len(matrix[0])
step = 0
queue = deque([root])
left = []
#forwards
while queue and step < rows:
step += 1
size = len(queue)
for _ in range(size):
r, c = queue.popleft()
left.append(matrix[r][c])
if r == 0:
level = [(i, step -i) for i in range(step+1)] #(r, c+1)
elif c == 0:
level = [(step-i, i) for i in range(step+1)]
queue += level
#logging.debug(f"queue: {queue}")
#logging.debug(f"left: {left}")
#raise Exception
#backwords
step = 0
queue = deque([root])
right = []
#forwards
while queue and step < rows-1:
step += 1
size = len(queue)
for _ in range(size):
r, c = queue.popleft()
right.append(matrix[rows-r-1][cols-c-1])
if r == 0:
level = [(i, step -i) for i in range(step+1)] #(r, c+1)
elif c == 0:
level = [(step-i, i) for i in range(step+1)]
queue += level
#logging.debug(f"queue: {queue}")
#logging.debug(f"right: {right}")
#raise Exception
right.reverse()
res = left + right
return res
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.