498.对角线遍历(中)

题目

法一、模拟

  • 分析由二维数组的特性可以得知,向右上方走实际上等于 x -= 1, y += 1, 向左下方走实际上等于 x+= 1, y -= 1

当向右上方走的时候,有两种情况会造成碰壁,因而需要转弯,
CASE 1: 碰到上方的壁 (x无法再 - 1),但还没碰到右方的壁(y可以 +1)
在这种情况下,下一步的坐标为 y += 1, 比如图里的 1 --> 2
CASE 2: 碰到右方的壁 (y无法再 +1)
在这种情况下, 下一步的坐标为 x += 1, 比如图里的 3 --> 6
向左下方走同理:
CASE 1: 碰到左方的壁 (y无法再 -1), 但还没有碰到下方的壁(x可以 +1)
在这种情况下,下一步的坐标为 x += 1, 比如图里的 4 --> 7
CSSE 2: 碰到下方的壁 (x无法再 +1)
在这种情况下,下一步的坐标为 y += 1, 比如图里的 8 --> 9

class Solution:
	def findDiagonalOrder(self, matrix):
		if not matrix or not matrix[0]:
			return []
		M, N = len(matrix), len(matrix[0])
		matrix_num = M * N
		count = 0
		x, y = 0, 0
		result = []
		direction = "up"
		while (count < matrix_num):
			count += 1
			result.append(matrix[x][y])
			# 向右上方向走
			if direction == "up":
				# 无需调换方向的条件(1.x>0 碰到上壁前, 2.y<n-1碰到右壁前)
				if x > 0 and y < N - 1:
					x -= 1
					y += 1
					continue
				else:
					direction = "down"
					# 碰到上壁:1 --> 2
					if x == 0 and y < N - 1:
						y += 1
					# 碰到右壁:3 --> 6
					elif y == N - 1:
						x += 1
			# 向左下方向走
			else:
				# 无需调换方向的条件(1.x < M 碰到下壁前, 2.y > 0 碰到右壁前)
				if x < M - 1 and y > 0:
					x += 1
					y -= 1
					continue
				else:
					direction = "up"
					# 碰左壁:4 --> 7
					if  y == 0 and x < M - 1:
						x += 1
					# 碰下壁:8 --> 9
					elif x == M - 1 :
						y += 1
		return result

法二、不等式

  • 一共有m+n−1m + n - 1m+n−1个对角线,对应左上角贴边走到右下角;右斜对角线是横纵坐标和为定值(左斜的话是差为定值)。
class Solution:
    def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
        m, n, ans = len(mat), len(mat[0]), []
        for k in range(m + n - 1):
            if not k % 2:
                ans += [mat[x][k-x] for x in range(min(m - 1, k), max(-1, k - n),-1)]
            else:
                ans += [mat[x][k-x] for x in range(max(0, k - n + 1), min(k + 1, m))]
        return ans
posted @ 2024-03-29 09:42  Frommoon  阅读(14)  评论(0编辑  收藏  举报