LeetCode 114 Flatten Binary Tree to Linked List
寫在前面
斷斷續續刷20多道LeetCode上的題了,之所以從這道題尅是記錄,是終於自己慢慢有思路了,不再參考一些discuss中的思路了,還有,終於一次通過編譯,LeetCode雖然有括號匹配等,但是相對於編譯器還是近乎是白板的,多加練習,戒掉對編譯器的依賴。另外,為了方便遷移,大多使用英語,註釋也使用英語,更為通用題目:
https://leetcode.com/problems/flatten-binary-tree-to-linked-list/description/thinking
1.首先,肯定需要遍歷二叉樹,對於遍歷二叉樹,我們一般是選擇遞歸
2.由二叉樹變為鏈表,我們首先要像,這兩種數據結構有什麽異同,相同點,二叉樹的root節點可以認為是鏈表的head節點,二叉樹的每個節點會有兩個指針域,分別指向left和right,而鏈表的每個節點有一個指針域,指向它的下一個節點。
3.我們要把左面的結構變成右邊的結構,很顯然,需要將根節點的right 指向左子樹,而left指向NULL就可以了,
4.遞歸調用上述方法遍歷左右子樹,這裏,我們需要考慮,左右子樹如何連在一起的,對比左右兩圖,顯然,需要將左子樹的最後一個節點的right指向右子樹,左子樹同樣置為NULL,
5.上述,只是考慮的一般情況,對於遞歸,我們需要考慮遞歸結束的條件,
- 二叉樹為空的時候,顯然,直接返回,
- 遍歷到葉節點時,如何操作
6.4 中提到,需要遍歷左右子樹,因為,我們不斷改變樹的結構,所以,遍歷之前,需要備份左右子樹,還需要保存最後節點的變量,因此,這裏,我們需要定義四個節點變量,當我們遍歷到左右子樹的最後一個節點,也是葉節點,需要一個last節點來保存我們的最後一個節點。所以,5 中的2,只有葉節點時如何操作,就很顯然了。
下面第一段代碼,是我第一次提交的代碼,雖然編譯沒問題,但submit時有錯誤,查看details,可以看到,通過了一部分,所以,大致思路是沒問題的,提示35行,我們自然會去查看35行,根據信息,我知道,需要對該節點判斷是否為空,
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {}View Code8 * }; 9 */ 10 class Solution { 11 public: 12 void flatten(TreeNode* root) { 13 TreeNode* last = nullptr; 14 preorder_trs(root,last); 15 } 16 private: 17 void preorder_trs(TreeNode* root,TreeNode* last){ 18 if(root == nullptr) return; 19 if(root->left==nullptr && root->right == nullptr){ 20 last = root; 21 return; 22 } 23 TreeNode* left = root->left; 24 TreeNode* right = root->right; 25 TreeNode* left_last = nullptr; 26 TreeNode* right_last = nullptr; 27 if(left){ 28 preorder_trs(left,left_last); 29 root->left = nullptr; 30 root->right = left; 31 last = left_last; 32 } 33 if(right){ 34 preorder_trs(right,right_last); 35 if(last){ 36 last->left = nullptr; 37 last->right = right; 38 } 39 40 last = right_last; 41 } 42 } 43 };
compile correct,but running error,details as follow
this means the node "last" also the left_last maybe nullptr,so we need judge the node whether nullptr or not,only if it is not null,we can let the right of the node point to the right sunTree.
The Accepted Answer:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 void flatten(TreeNode* root) { 13 TreeNode* last; 14 preorder_trs(root,last); 15 } 16 private: 17 void preorder_trs(TreeNode* root,TreeNode* &last){ 18 if(root ==nullptr) return; 19 if(root->left==nullptr && root->right ==nullptr) { 20 last = root; 21 return; 22 } 23 TreeNode* left = root->left; 24 TreeNode* right = root->right; 25 TreeNode* left_last = nullptr; 26 TreeNode* right_last = nullptr; 27 if(left){ 28 preorder_trs(left,left_last); 29 root->left = nullptr; 30 root->right = left; 31 last = left_last; 32 } 33 if(right){ 34 preorder_trs(right,right_last); 35 if(left_last){ 36 //last->left = nullptr; 37 left_last->right = right; 38 } 39 last = right_last; 40 } 41 } 42 };View Code
Two changes:
first: line 17, pass by value changed to pass by reference()
second,line 35,after I had added the condition to judge the last is nullptr or not ,it was also an wrong answer,so the condition changed to if(left_last){} , It would have been to judge the left_last,because of having assigned left_last to the last,why this is wrong ,I have not knew, Welcome To Dicuss!!!
寫在最後
這次認真寫博客還有一個收獲就是學會了使用graphviz畫數據結構的圖。我是一個追求高效率的人,看別人的博客數據結構圖畫的都很美觀,我想,不可能都是用PowerPoint或Visio畫的吧,那也太費時了,所以,我就Google了,還真Google到了,於是就趕緊安裝試了試,但最初畫出來的好醜啊,如下:
是不是看著很別扭,於是,我又Google了,看有沒有可以改進的辦法,找了半天還真找到了,也感謝這篇博客的博主:https://blog.csdn.net/theonegis/article/details/71772334
其實,不用像博主那樣保存為.gvpr ,保存為.gv就可以了,還是因為我懶,因為,我不知道博主說的那種格式文件,我安裝的graphviz能不能支持(雖然我都是用Sublime作為編輯器,命令行執行),所以,我就寫成了graphviz默認的.gv格式了。這就是寫博客的好處之一,除了幫你整理思路,還督促你不斷學習新東西。
LeetCode 114 Flatten Binary Tree to Linked List