题目
解法1:暴力
按照题目的描述,不断的去收集叶节点,然后断开这些叶节点
class Solution {
public:
void helper(TreeNode* root,TreeNode* parent, vector<int>& tmp, string child){
if(!root) return;
if(!root->left && !root->right){
tmp.push_back(root->val);
if(child == "left") parent->left = nullptr;
if(child == "right") parent->right = nullptr;
return;
}
helper(root->left,root,tmp,"left");
helper(root->right,root,tmp,"right");
return;
}
vector<vector<int>> findLeaves(TreeNode* root) {
if(!root) return {};
if(!root->left && !root->right) return {{root->val}};
vector<vector<int>> ans;
while(true){
if(!root->left && !root->right) {
ans.push_back({root->val});
return ans;
}
vector<int> tmp;
TreeNode* parent = new TreeNode();
helper(root,parent,tmp,"");
ans.push_back(tmp);
}
return ans;
}
};
时间复杂度:O(D*N),D为树的的深度,N为节点个数,这个helper函数需要访问D次,每次访问所有节点
空间复杂度:O(D),递归带来的
解法2: two pass
核心思想是,从叶节点开始往上数,到当前节点的深度(是倒过来的深度),决定了这个节点在答案中的位置
首先获得深度,预定义好答案的长度,然后更求深度一样的在每个位置加入答案
class Solution {
public:
int getDepth(TreeNode* root){
if(!root) return 0;
return max(getDepth(root->left),getDepth(root->right)) + 1;
}
int helper(TreeNode* root,vector<vector<int>>& ans){
if(!root) return -1;
int ind = max(helper(root->left,ans),helper(root->right,ans)) + 1;
ans[ind].push_back(root->val);
return ind;
}
vector<vector<int>> findLeaves(TreeNode* root) {
int depth = getDepth(root);
// cout << depth << endl;
vector<vector<int>> ans(depth);
helper(root,ans);
return ans;
}
};
时间复杂度:O(2N)
解法3:one pass
无需预先求的深度,如果当前节点获得的深度已经大于答案的长度,就增加答案的长度即可
class Solution {
public:
int helper(TreeNode* root,vector<vector<int>>& ans){
if(!root) return -1;
int ind = max(helper(root->left,ans),helper(root->right,ans)) + 1;
if(ind >= ans.size()){
ans.push_back({root->val});
}else{
ans[ind].push_back(root->val);
}
return ind;
}
vector<vector<int>> findLeaves(TreeNode* root) {
vector<vector<int>> ans;
helper(root,ans);
return ans;
}
};
时间复杂度:O(N)