• 代码题(66)— 二叉树的所有路径、最长同值路径


    1、257. 二叉树的所有路径 

    给定一个二叉树,返回所有从根节点到叶子节点的路径。

    说明: 叶子节点是指没有子节点的节点。

    示例:

    输入:
    
       1
     /   
    2     3
     
      5
    
    输出: ["1->2->5", "1->3"]
    
    解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3

      这道题给我们一个二叉树,让我们返回所有根到叶节点的路径,跟之前那道Path Sum II很类似,比那道稍微简单一些,不需要计算路径和,只需要无脑返回所有的路径即可,那么思路还是用递归来解,博主之前就强调过,玩树的题目,十有八九都是递归,而递归的核心就是不停的DFS到叶结点,然后在回溯回去。在递归函数中,当我们遇到叶结点的时候,即没有左右子结点,那么此时一条完整的路径已经形成了,我们加上当前的叶结点后存入结果res中,然后回溯。注意这里结果res需要reference,而out是不需要引用的,不然回溯回去还要删除新添加的结点,很麻烦。为了减少判断空结点的步骤,我们在调用递归函数之前都检验一下非空即可,代码而很简洁,参见如下:

    /**
     * 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:
        vector<string> binaryTreePaths(TreeNode* root) {
            vector<string> res;
            if(root == nullptr)
                return res;
            string temp = "";
            allPath(root, temp, res);
            return res;
        }
        void allPath(TreeNode* root, string temp, vector<string>& res){
            if(!root->left && !root->right)
                res.push_back(temp+ to_string(root->val));
            if(root->left)
                allPath(root->left, temp+to_string(root->val)+ "->", res);
            if(root->right)
                allPath(root->right, temp+to_string(root->val)+ "->", res);
            
        }
    };

    2、687. 最长同值路径

    给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。

    注意:两个节点之间的路径长度由它们之间的边数表示。

      这道题让我们求最长的相同值路径,跟之前那道 Count Univalue Subtrees 十分的类似,解法也很类似。对于这种树的路径问题,递归是不二之选。在递归函数中,我们首先对其左右子结点调用递归函数,得到其左右子树的最大相同值路径长度,下面就要来看当前结点和其左右子结点之间的关系了,如果其左子结点存在且和当前节点值相同,则left自增1,否则left重置0;同理,如果其右子结点存在且和当前节点值相同,则right自增1,否则right重置0。然后用left+right来更新结果res。而调用当前节点值的函数只能返回left和right中的较大值,因为如果还要跟父节点组path,就只能在左右子节点中选一条path,当然选值大的那个了,什么意思呢,举个例子来说吧,比如下面的这棵二叉树:

          1
         / 
        4   5
       /    
      4   4   5
     /
    4

      若此时的node是只有两个结点的第二层的那个结点4,那么分别对其左右子结点调用递归,会得到 left = 1, right = 0,因为此时要跟结点4组成path,所以肯定挑左子结点(有两个4的那条边),那你会问为啥不能连上右子结点的那个4,这整条长度为3的path(left+right,此时的left和right已经分别自增1了,left=2,right=1)其实我们已经用来更新过结果res了。需要注意的是我们的递归函数helper返回值的意义,并不是经过某个结点的最长路径的长度,最长路径长度保存在了结果res中,不是返回值,返回的是以该结点为终点的最长路径长度,这样回溯的时候,我们还可以继续连上其父结点,比如若根结点也是4的话,那么回溯到根结点的时候,路径长度又可以增加了,参见代码如下:

    /**
     * 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 longestUnivaluePath(TreeNode* root) {
            if(root == nullptr)
                return 0;
            int res = 0;
            helper(root, res);
            return res;
        }
        int helper(TreeNode* root, int& res){
            if(root == nullptr)
                return 0;
            int left = helper(root->left, res);
            int right = helper(root->right, res);
            left = (root->left && root->val == root->left->val) ? left+1 : 0;
            right = (root->right && root->val == root->right->val) ? right+1 : 0;
            res = max(res, left+right);
            return max(left, right);
        }
    };
  • 相关阅读:
    jQuery获取各种标签的文本和value值
    python中base64编码与解码
    Django 的 slug url 正则匹配
    JavaScript base64 加密解密
    HTML引入外部JS文件
    CSS样式的引入方式
    Django 配置404页面
    selenium 基本操作
    python 启动pydoc查看文档
    selenium webdriver
  • 原文地址:https://www.cnblogs.com/eilearn/p/14777561.html
Copyright © 2020-2023  润新知