题号 | 做出 | 未做 |
---|---|---|
1528. 重新排列字符串 | √ | |
1529. 灯泡开关 IV | √ | |
1530. 好叶子节点对的数量 | √ | |
1531. 压缩字符串 II | √ |
通过率:50%
1528. 重新排列字符串
1529. 灯泡开关 IV
1530. 好叶子节点对的数量
题目描述:
给你二叉树的根节点 root 和一个整数 distance 。 如果二叉树中两个 叶 节点之间的 最短路径长度 小于或者等于
distance ,那它们就可以构成一组 好叶子节点对 。 返回树中 好叶子节点对的数量 。
输入:root = [1,2,3,null,4], distance = 3
输出:1
解释:树的叶节点是 3 和 4 ,它们之间的最短路径的长度是 3 。这是唯一的好叶子节点对。
######################################################################################
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-good-leaf-nodes-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 较复杂的递归实现。
题目理解
对于每一个子树(
T
r
e
e
(
i
)
Tree(i)
Tree(i)即以下标
i
i
i为根节点的树),距离为
D
D
D的对应的好叶子节点数(记为
N
u
m
s
f
(
T
r
e
e
(
i
)
,
D
)
Numsf(Tree(i),D)
Numsf(Tree(i),D))。都等于
N
u
m
s
f
(
T
r
e
e
(
i
)
,
D
)
=
N
u
m
s
f
(
T
r
e
e
(
i
l
e
f
t
)
,
D
)
+
N
u
m
s
f
(
T
r
e
e
(
i
r
i
g
h
t
)
,
D
)
+
N
u
m
s
f
(
T
r
e
e
(
i
)
,
D
−
1
)
×
N
u
m
s
f
(
T
r
e
e
(
i
)
,
D
−
1
)
Numsf(Tree(i),D) = Numsf(Tree(i_{left}),D) + Numsf(Tree(i_{right}),D) + Numsf(Tree(i),D-1)×Numsf(Tree(i),D-1)
Numsf(Tree(i),D)=Numsf(Tree(ileft),D)+Numsf(Tree(iright),D)+Numsf(Tree(i),D−1)×Numsf(Tree(i),D−1)
则可以通过递归从叶子节点开始计算
N
u
m
s
f
(
T
r
e
e
(
i
)
,
D
)
Numsf(Tree(i),D)
Numsf(Tree(i),D)直到根节点记为最总结果。接下来的问题就是如何实现这个
N
u
m
s
f
Numsf
Numsf函数。
题解
题解有两个地方需要实现:
- N u m s f Numsf Numsf函数的计算
- 深度遍历计算
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int countPairs(TreeNode* root, int distance) {
if(!root)
return 0;
auto [depth, res] = getPath(root, distance);
return res;
}
private:
pair<vector<int>, int> getPath(TreeNode* node, int distance)
{
vector<int> depth(distance+1, 0); //depth[i]的含义就是当深度为i时对应的叶子数,depth[0] = 1
//表示的是深度为0的时候叶子为1,即本身就是叶子节点。
if(node->left == NULL && node->right == NULL){
depth[0] = 1;
return make_pair(depth, 0);
}
vector<int> leftDepth(distance+1, 0);
vector<int> rightDepth(distance+1, 0);
int leftnum = 0, rightnum = 0;
if(node->left){
tie(leftDepth, leftnum) = getPath(node->left, distance);
}
if(node->right){
tie(rightDepth, rightnum) = getPath(node->right, distance);
}
//在计算当前节点的总叶子数时,需要考虑到leftDepth和rightDepth分别是当前节点的
//左右孩子节点,所以leftDepth[i]表示的第i深度的叶子节点数其实对应的是当前节点的第i+1层。
for(int i = 0; i < distance; ++i){
depth[i+1] += leftDepth[i];
depth[i+1] += rightDepth[i];
}
int cnt = 0; //cnt的计算过程就是Numsf函数的实现过程
for(int i = 0; i <= distance; ++i){
for(int j = 0; i+j+2 <= distance; ++j)
cnt += (leftDepth[i]*rightDepth[j]);
}
return make_pair(depth, cnt+leftnum+rightnum);
}
};