【树】B044_LC_二叉树的垂序遍历(嵌套 map + set 记录坐标)

一、Problem

给定二叉树,按垂序遍历返回其结点值。

对位于 (X, Y) 的每个结点而言,其左右子结点分别位于 (X-1, Y-1) 和 (X+1, Y-1)。

把一条垂线从 X = -infinity 移动到 X = +infinity ,每当该垂线与结点接触时,我们按从上到下的顺序报告结点的值( Y 坐标递减)。

如果两个结点位置相同,则首先报告的结点值较小。

按 X 坐标顺序返回非空报告的列表。每个报告都有一个结点值列表。
【树】B044_LC_二叉树的垂序遍历(嵌套 map + set 记录坐标)_第1张图片

输入:[1,2,3,4,5,6,7]
输出:[[4],[2],[1,5,6],[3],[7]]
解释:
根据给定的方案,值为 5 和 6 的两个结点出现在同一位置。
然而,在报告 "[1,5,6]" 中,结点值 5 排在前面,因为 5 小于 6。

提示:

树的结点数介于 1 和 1000 之间。
每个结点值介于 0 和 1000 之间。

二、Solution

方法一:嵌套 map

思路

首先我们在遍历时肯定要记录某个结点的 (x, y),当遍历到 x = k 这条垂线时,这条线上可能会有多个结点,所以,我们需要一个 map,key 为 x 坐标,对于 y = m 这条线也可能存在多个结点,所以我们还需要一个 map,它的键是 y 轴坐标,那么 value 就肯定是结点的值

为了更好写一点,我选择 C++ 咯…

class Solution {
public:
	map<int, map<int, set<int>, greater<int>>> m;
	void dfs(TreeNode* root, int x, int y) {
		if (root == NULL)
			return;
		m[x][y].insert(root->val);
		dfs(root->left, x-1, y-1);
		dfs(root->right, x+1, y-1);
	}
    vector<vector<int>> verticalTraversal(TreeNode* root) {
    	dfs(root, 0, 0);
    	vector<vector<int>> ans;
    	for (auto& pos : m) {
    		vector<int> vt;
            for (auto& [x, p] : pos.second)
			for (auto& val : p)
				vt.push_back(val);
			ans.push_back(vt);
		}
		return ans;
    }
};

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

你可能感兴趣的:(#,树)