1. 程式人生 > >【leetcode】Flatten Binary Tree to Linked List

【leetcode】Flatten Binary Tree to Linked List

模式 分析 事情 oot left stat log 這樣的 要求

分析:

問題是將給定的二叉樹變換成令一種形式,這樣的類型的問題。其模式是,將左子樹變換成某種形式,右子樹也變換成這樣的形式,然後再與根結點按規定的方式連接起來,那麽總體就變換完畢了。

這個題我們就能夠採用這樣的形式。麻煩的地方就是在進行連接的時候。我們如果根為root,左子樹變換後的根為root_left。右子樹變換後的根為 root_right。那麽連接的時候應該是root->right = root_left,再連接root_right的時候。應該是root_left所指向的一系列結點的最後一個結點和root_right連接。如果該結點為tail_left,那麽就應該是tail_left->right = root_right。這樣總體就連接好了。在詳細連接的時候。可能要考慮某些結點為NULL的情況。

//

TreeNode *&link(TreeNode *&root)
	{
		if(root == NULL || root->left == NULL && root->right == NULL) 
			return root;
		TreeNode *root_left = NULL;
		TreeNode *root_right = NULL;
		root_left = link(root->left);
		root_right = link(root->right);
		if(root_left != NULL)
		{
			TreeNode *tail = root_left;
			//find the last one of root->left.
			while(tail->right) tail = tail->right;
			tail->right = root_right;
		}
		else
			root_left = root_right;
		root->right = root_left;
		root->left = NULL;
		return root;
	}
	void flatten(TreeNode *root) {
		if(root == NULL) return;
		root = link(root);
	}

我們再換個思路,題目中提示我們這樣的形式事實上是樹的先根遍歷的結果。那麽我們回憶下基本先根遍歷是怎麽處理的,我們都是簡單的將根結點的val值進行打印。如今如果能夠用額外的空間,那麽我們就能夠將先根遍歷中的根結點放到一個順序容器中。然後將每一個結點連起來就是題目要求的了。可是題目的意思非常明顯不希望這樣做,但我們還是希望用這樣的形式,那怎麽辦呢?事實上我們不難發現,轉換後的樹形式上就是個單鏈表。那麽問題就轉換成單鏈表的建立。
void preVisit(TreeNode*& pre, TreeNode*root)
	{
		if(root == NULL)
			return;
		TreeNode *right = root->right;
		TreeNode *left = root->left;
		root->left = NULL;
		if(pre == NULL)
			pre = root;
		else
		{
			pre->right = root;
			pre = root;
		}
		if(left)
			preVisit(pre, left);
		if(right)
			preVisit(pre, right);
	}

上面的代碼就是典型的先根遍歷的模板。僅僅是模板中的萬能visit函數做了一點略微復雜的事情。

void flatten(TreeNode* root)
	{
		if(root = NULL) return;
		TreeNode *pre = NULL;
		preVisit(pre, root);
	}

總結:還是重復前面文章中重復說過的。樹的基本遍歷的模式一定要熟記於胸,非常多衍生的問題都是能夠套用模板的。

【leetcode】Flatten Binary Tree to Linked List