力扣-114-二叉树展开为链表

  1. 按照先序遍历展开
  2. 展开后仍然为TreeNode,只是左孩子指针一律置空

关键在于这个先序的访问过程与各个节点指针的修改操作如何统一不冲突

首先就可以排除先序遍历,瞄一眼评论其实是可以先遍历右边,从后往前构造的(我也有点这想法,之前反转链表就有这种从后往前的递归思路,只是不太好想)

public:
	// 使用一个指针保存了最后一个节点
	TreeNode* lastNode = nullptr;
	void flatten(TreeNode* root) {
		if (!root) return;
		flatten(root->right);
		flatten(root->left);
		root->right = lastNode;
		root->left = nullptr;
		lastNode = root;
	}

起码看起来非常优雅简洁,使用了额外的指针保存上一个(最后操作)节点,配合右左根的遍历方式,实现从后往前拼接链表

但是遗憾的是这不是一个原地算法

原地怎么做呢?前面说了,先序肯定是不行的,那就考虑后序

官方题解

官解1:前序遍历+遍历修改指针

这是最简单粗暴的办法,一次前序遍历二叉树,得到的序列(节点指针)放到数组中,此时数组序列即是展开后的序列,那么剩下唯一需要做的就只有修改各节点的左右孩子节点指针:

  • 左孩子指针修改为空
  • 右孩子指针指向数组中的下一个元素

算法时间复杂度是两次遍历2N,空间复杂度是数组长度N

那么能不能把这两步步骤同步进行呢?乍一看矛盾的,做不到边改指针边正常遍历

posted @ 2022-12-14 09:04  YaosGHC  阅读(27)  评论(0)    收藏  举报