1. 題目
給你一棵二叉樹,請按以下要求的順序收集它的全部節點:
- 依次從左到右,每次收集並刪除所有的葉子節點
- 重複如上過程直到整棵樹爲空
示例:
輸入: [1,2,3,4,5]
1
/ \
2 3
/ \
4 5
輸出: [[4,5,3],[2],[1]]
解釋:
1. 刪除葉子節點 [4,5,3] ,得到如下樹結構:
1
/
2
2. 現在刪去葉子節點 [2] ,得到如下樹結構:
1
3. 現在刪去葉子節點 [1] ,得到空樹:
[]
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/find-leaves-of-binary-tree
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
2. 解題
類似題目:LeetCode 156. 上下翻轉二叉樹(DFS)*
- 先自底向上,翻轉二叉樹,把子節點的 left,指向父節點
- 同時記錄父節點有多少個子節點(0,1,2,)
- 把葉子節點加入隊列
- 開始BFS,出隊一個,就把該節點的 left (原來的父節點的子節點計數 -1)
- 當節點的子節點計數爲0時,它就變成了葉子節點,可以入隊了
class Solution {
vector<vector<int>> ans;
queue<TreeNode*> q;
unordered_map<TreeNode*, int> map;//父節點底下掛着幾個子節點
public:
vector<vector<int>> findLeaves(TreeNode* root) {
reverse(root);//上下翻轉二叉樹
while(!q.empty())
{
int size = q.size(), i = 0;
vector<int> lv(size);
while(size--)
{
TreeNode *cur = q.front();
q.pop();
map[cur->left]--;//原父節點的子節點計數-1
lv[i++] = cur->val;//當前值寫入答案
if(cur->left && map[cur->left]==0)//父節點計數爲0,可以入隊
q.push(cur->left);
}
ans.push_back(lv);
}
return ans;
}
TreeNode* reverse(TreeNode* root)
{
if(!root) return NULL;
auto l = root->left;
auto r = root->right;
if(!l && !r)
q.push(root);//葉子節點加入隊列
map[root] += (l?1:0) + (r?1:0);//記得加括號,子節點個數
root->left = NULL;//斷開子節點
root->right = NULL;
auto lc = reverse(l);
auto rc = reverse(r);
if(lc)
lc->left = root;//子節點的left指向父節點
if(rc)
rc->left = root;
return root;
}
};
0 ms 9 MB
- 上面做法遍歷了2次樹,更簡單的做法,按照樹的高度(2側子樹的最大高度 + 1自己)來分組
class Solution {
vector<vector<int>> ans;
public:
vector<vector<int>> findLeaves(TreeNode* root) {
dfs(root);
return ans;
}
int dfs(TreeNode* root)
{
if(!root) return -1;
int hl = dfs(root->left);
int hr = dfs(root->right);
int hcur = max(hl, hr) + 1;
if(ans.size() <= hcur)
ans.push_back({});
ans[hcur].push_back(root->val);
return hcur;
}
};
4 ms 9.1 MB
我的CSDN博客地址 https://michael.blog.csdn.net/
長按或掃碼關注我的公衆號(Michael阿明),一起加油、一起學習進步!