一:题意
一开始没读懂题,很尴尬!
给定一棵二叉树,然后对节点进行编码,把节点坐标算出来,把一条垂直线上的节点返回。
样例:
输入:
转化为坐标点:
转化规则为:初始化根节点坐标为(0,0),左儿子坐标为(X-1,Y-1),右儿子坐标为(X+1,Y-1),下图中红色点的值为节点值。
看坐标图,X=-1这条垂直线上有节点9,X=0这条垂直线上有节点3,15,依次类推。
所以返回结果为[[9],[3,15],[20],[7]]
二:思路
- 首先遍历二叉树,把树中的节点转化为二维坐标系下的坐标
- 对坐标进行排序,排序规则为:
当X相同时,按照Y轴从大到小排序,取出节点值
当X,Y都相同时,按照节点值从小到大排序 - 然后对二维坐标系下的坐标进行遍历
三:实现
广度优先遍历二叉树,当然也可以深度优先搜索遍历
class Solution(object):
def verticalTraversal(self, root):
if not root: return []
queue = [(0, 0, root)] # (x, y, node)
pos = [] # (x, y, val)
while queue:
x, y, node = queue.pop()
pos.append((x, y, node.val))
if node.left:
queue = [(x-1, y-1, node.left)] + queue
if node.right:
queue = [(x+1, y-1, node.right)] + queue
pos.sort(key = lambda x : (x[0], -x[1], x[2])) # 按照x从小到大,然后按照y从大到小,再按val从小到大
res = []
res.append([pos[0][2]]) # 首先初始化
for i in range(1, len(pos)):
if pos[i][0] == pos[i-1][0]:
res[-1].append(pos[i][2]) # 已经存在了
else:
res.append([pos[i][2]])
return res