路径之和

1. 二叉树是否存在一条从根节点到叶节点的路径和为target的路径。
方法一:递归。return hasPath(root->left, target-root->val)||hasPath(root->right, target-root->val)
方法二:bfs。两个队列,一个记录访问的节点,一个记录访问结点时的路径和,当访问到叶节点且路径和==target,返回true

2. 列举二叉树中从根节点到叶节点的路径和为target的路径。深搜回溯法:ans和tmp,dfs二叉树,若root->为null,返回,tmp.push_back(root->val),如果当前节点为叶节点且当前路径和为target,ans.push_back(tmp),接下来如此遍历root的左节点和右节点,tmp.pop_back(),恢复路径之前的状态,去掉根节点的左节点,接下来准备加上右节点。求根节点到叶节点的路径连成的数字之和以及从叶节点到根节点连成的字符串的最小字典序字符串,思路基本与本题一致。数字之和不需要额外申请一个整数数组,记录访问到当前节点的sum,若当前节点为叶节点,sum加到res上;求路径的最小字典序字符串,得到路径记得反转,并比较得到最小的。C++的比较函数是返回两个值的大小比较表达式

3. 二叉树中节点之间路径和为target的路径数量。
方法一:深搜。按照路径总和2的解决思路,维护深度遍历时的根节点到当前访问节点的路径,累加以当前节点为叶节点的和为target的路径数量;另外一种深搜的思路:以root为根节点的路径之和3=以root开头的和为target的路径数量+以root->left为根节点的路径之和3+以root->right为根节点的路径之和3,问题不断这样分解递归处理;与上个思路相似,计算一个节点开头的和为target的路径数量rootSum,深度遍历二叉树计算每个节点的rootSum,累积和为结果
方法二:前缀和。注意prefix的初始化,设prefix[0]=1,表示若root->val==target,即根节点形成的路径和为target,数量记为1。前序遍历二叉树,cur表示从根节点访问到当前节点的路径和,prefix[cur-target]+dfs(root->left, cur, target)+dfs(root->right, cur, target)表示以root及其后代节点为结尾的和为target的路径数量,注意回溯改变prefix[cur]的值,往后讨论需要包含当前节点的当前路径,prefix[cur]++,否则prefix[cur]--

二叉树最长同值路径的长度,同值路径的意思是两节点间的路径上节点的值都相同。前序遍历二叉树,计算包含当前遍历节点的同值路径的最大值,注意根节点为当前遍历的节点时,根节点的左边和右边可连起来,形成更长的同值路径,若根节点不是当前遍历的节点,需要在左边和右边可连成的同值路径长度上选择最大值,具体代码看白云悠远刷题题解。另外,官方算法实现比我摸索的成熟,采用后序遍历,获取左节点和右节点为根节点的子树且包含该根节点的最长同值路径长度,左右节点再与根节点连接,看形成的包含根节点的最长同值路径,并记录结果,该递归函数返回根节点分别与左、右子树连接包含根节点的最长同值路径的长度的最大值。官方题解换句话说,left、right分别表示以左右子树根节点为首的最长同值路径长度,若root->left->val==root->val, left++, else left=0, right同理,res=max(res, left+right),深搜函数返回max(left, right),即以当前根节点为首的最长同值路径长度,递归到开头的子树那里。深搜整棵树,res即为结果。

二叉树中存在的节点间路径和的最大值,定义深搜函数,分别向左节点和右节点深搜,得到left和right,left=max(left,0),right同理,res=max(res,root->val+left+right),返回root->val+max(left,right)。深搜root,res即为结果。

参考链接:112. 路径总和
113. 路径总和 II
437. 路径总和 III
687. 最长同值路径
124.二叉树中的最大路径和
129. 求根节点到叶节点数字之和
988. 从叶结点开始的最小字符串

创建于2022.3.16/15.48,修改于2022.3.22/15.52

#recursion #bfs #backtracking #dfs