Leetcode刷题——树篇7

文章目录

  • 7、树(中等篇3)
    • 7.1、144. 二叉树的前序遍历
    • 7.2、96. 不同的二叉搜索树
    • 7.3、1123. 最深叶节点的最近公共祖先
    • 7.4、429. N叉树的层序遍历
    • 7.5、105. 从前序与中序遍历序列构造二叉树
    • 7.6、889. 根据前序和后序遍历构造二叉树
    • 7.7、199. 二叉树的右视图
    • 7.8、508. 出现次数最多的子树元素和
    • 7.9、129. 求根到叶子节点数字之和
    • 7.10、951. 翻转等价二叉树

7、树(中等篇3)

7.1、144. 二叉树的前序遍历

给定一个二叉树,返回它的 前序 遍历。

示例:

输入: [1,null,2,3]
在这里插入图片描述
输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析:首先递归是不可能递归了,递归简单。
接下来是要实现非递归的方法。

题解代码(C++):

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        if(root==NULL) return res;
        stack<TreeNode*> s;
        s.push(root);
        while(!s.empty()){
            TreeNode* cur = s.top();s.pop();
            res.push_back(cur->val);
            if(cur->right) s.push(cur->right);
            if(cur->left) s.push(cur->left);
        }
        return res;
    }
};

题解代码(Java):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<Integer>();
        if(root==null) return res;
        Stack<TreeNode> s = new Stack<TreeNode>();
        s.push(root);
        while(!s.isEmpty()){
            TreeNode cur = s.pop();
            res.add(cur.val);
            if(cur.right!=null) s.push(cur.right);
            if(cur.left!=null) s.push(cur.left);
        }
        return res;
    }
}

题解代码(Python):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        if root is None:
            return res
        s = []
        s.append(root)
        while len(s)>0:
            cur = s.pop()
            res.append(cur.val)
            if cur.right is not None:
                s.append(cur.right)
            if cur.left is not None:
                s.append(cur.left)
        return res

7.2、96. 不同的二叉搜索树

给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?

示例:

输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
Leetcode刷题——树篇7_第1张图片
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-binary-search-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析:
根据例子n=3,假设有1,2,3三个值。
设以1为根节点,左子树节点数为0,右子树节点数为2。
设一个函数G(n)表示n个结点能构成满足题意的二叉树个数,
那么以1为根节点时,能构成的个数为G(0) x G(2)=2;
以2为根节点时,能构成的个数为G(1) x G(1)=1;
以3为根节点时,能构成的个数为G(2) x G(0)=3;
累加起来就是结果了。
显然G(0)=G(1)=1,不难得到G(n)的递推公式。
在这里插入图片描述
所以本题可以用动态规划来做。

题解代码(C++):

class Solution {
public:
    int numTrees(int n) {
        vector<int> G(n+1,0);
        G[0]=G[1]=1;
        for(int i=2;i<=n;i++)
            for(int j=1;j<=i;j++)
                G[i] += G[j-1]*G[i-j];
        return G[n];
    }
};

题解代码(Java):

class Solution {
    public int numTrees(int n) {
        int[] G = new int[n+1];
        G[0] = G[1]=1;
        for(int i=2;i<=n;i++){
            for(int j=1;j<=i;j++){
                G[i]+=G[j-1]*G[i-j];
            }
        }
        return G[n];
    }
}

题解代码(Python):

class Solution:
    def numTrees(self, n: int) -> int:
        G = [0]*(n+1)
        G[0], G[1] = 1, 1

        for i in range(2, n+1):
            for j in range(1, i+1):
                G[i] += G[j-1] * G[i-j]

        return G[n]

7.3、1123. 最深叶节点的最近公共祖先

给你一个有根节点的二叉树,找到它最深的叶节点的最近公共祖先。

回想一下:

叶节点 是二叉树中没有子节点的节点 树的根节点的 深度 为 0,
如果某一节点的深度为 d,那它的子节点的深度就是 d+1 如果我们假定 A
是一组节点 S 的 最近公共祖先,S 中的每个节点都在以 A 为根节点的子树中,且 A 的深度达到此条件下可能的最大值。

示例 1:

输入:root = [1,2,3] 输出:[1,2,3]
示例 2:

输入:root = [1,2,3,4] 输出:[4]
示例 3:

输入:root = [1,2,3,4,5] 输出:[2,4,5]

提示:

给你的树中将有 1 到 1000 个节点。 树中每个节点的值都在 1 到 1000 之间。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of- deepest-leaves
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析:题目表述不太清晰,反正我理解了半天也没懂什么意思(我可能比较春虫虫)。例子说的是什么鬼!!!(其实例子返回的是一棵树,以最近公共祖先为根节点的树)

假设一棵树,根节点为root,这个树最深叶子结点在左子树,不在右子树,那么左子树的高度一定是大于右子树的高度的,然后最深叶子结点的最近公共祖先,也是肯定出现在左子树上的,递归进入左子树。
当某个结点,左右子树高度一样的时候,那么这个结点就是最近公共祖先。

题解代码(C++):

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int getHight(TreeNode* root){
        if(root==NULL) return 0;
        return max(getHight(root->left),getHight(root->right))+1;
    }
    TreeNode* lcaDeepestLeaves(TreeNode* root) {
        if(root==NULL) return NULL;
        int leftHight = getHight(root->left);
        int rightHight = getHight(root->right);
        if(leftHight==rightHight) return root;
        else return leftHight>rightHight?lcaDeepestLeaves(root->left):lcaDeepestLeaves(root->right);
    }
};

题解代码(Java):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int getHight(TreeNode root){
        if(root==null) return 0;
        else return Math.max(getHight(root.left),getHight(root.right))+1;
    }
    public TreeNode lcaDeepestLeaves(TreeNode root) {
        if(root==null) return null;
        int left=getHight(root.left);
        int right = getHight(root.right);
        if(left==right) return root;
        else return left>right?lcaDeepestLeaves(root.left):lcaDeepestLeaves(root.right);
    }
}

题解代码(Python):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def getHight(self,root:TreeNode)->int:
        if root is None:
            return 0
        else:
            return max(self.getHight(root.left),self.getHight(root.right))+1

    def lcaDeepestLeaves(self, root: TreeNode) -> TreeNode:
        if root is None:
            return None
        left = self.getHight(root.left)
        right = self.getHight(root.right)
        if left==right:
            return root
        else:
            return self.lcaDeepestLeaves(root.left) if left>right else self.lcaDeepestLeaves(root.right)

7.4、429. N叉树的层序遍历

给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。

例如,给定一个 3叉树 :

Leetcode刷题——树篇7_第2张图片

返回其层序遍历:

[ [1],
[3,2,4],
[5,6] ]

说明:

树的深度不会超过 1000。 树的节点总数不会超过 5000。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析:就是二叉树的层次遍历的升级版,很简单。

题解代码(C++):

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        vector<vector<int>> res;
        if(root==NULL) return res;
        queue<Node*> q;
        q.push(root);
        while(!q.empty()){
            int count = q.size();
            vector<int> v;
            while(count>0){
                Node* cur = q.front();q.pop();
                v.push_back(cur->val);
                for(Node* child:cur->children){
                    q.push(child);
                }
                count--;
            }
            res.push_back(v);
        }
        return res;
    }
};

题解代码(Java):

/*
// Definition for a Node.
class Node {
    public int val;
    public List children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> res = new LinkedList<List<Integer>>();
        if(root==null) return res;
        Queue<Node> q = new LinkedList<Node>();
        q.offer(root);
        while(!q.isEmpty()){
            int count = q.size();
            List<Integer> v = new LinkedList<Integer>();
            while(count>0){
                Node cur = q.poll();
                v.add(cur.val);
                for(Node child:cur.children){
                    q.offer(child);
                }
                count--;
            }
            res.add(v);
        }
        return res;
    }
}

题解代码(Python):

"""
# Definition for a Node.
class Node:
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""

class Solution:
    def levelOrder(self, root: 'Node') -> List[List[int]]:
        res = []
        if root is None:
            return res
        q=[]
        q.append(root)
        while len(q)>0:
            count = len(q)
            v = []
            while count>0:
                cur = q.pop(0)
                v.append(cur.val)
                for child in cur.children:
                    q.append(child)
                count-=1
            res.append(v)
        return res

7.5、105. 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。
注意: 你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

   3   
  / \   
 9  20
   /  \    
  15   7

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析:都知道已知前序遍历和中序遍历就能唯一确定一棵二叉树,那么如何实现这个算法呢?根据手动模拟建树,前序遍历用于确定创建的结点,中序遍历用于分组。
首先把中序遍历存到map中,方便取分组索引,不需要每次都遍历求分组索引。
然后根据前序遍历建立结点,最后递归就好了。

题解代码(C++):

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    map<int,int> mymap;
    vector<int> preorder;
    TreeNode* buildTreeHelper(int &index,int left,int right){
        if(left>right) return NULL;
        TreeNode* root=new TreeNode(this->preorder[index++]);
        root->left=buildTreeHelper(index,left,this->mymap[root->val]-1);
        root->right=buildTreeHelper(index,this->mymap[root->val]+1,right);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size()==0) return NULL;
        int index=0;
        this->preorder=preorder;
        for(int a:inorder)
            this->mymap[a] = index++;
        index = 0;
        return buildTreeHelper(index,0,preorder.size()-1);
    }
};

题解代码(Java):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    Map<Integer,Integer> mymap;
    int index=0;    
    int[] preorder;
    public TreeNode buildTreeHelper(int left,int right){
        if(left>right) return null;
        TreeNode root = new TreeNode(this.preorder[this.index++]);
        root.left = buildTreeHelper(left,this.mymap.get(root.val)-1);
        root.right = buildTreeHelper(this.mymap.get(root.val)+1,right);
        return root;
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length==0) return null;
        this.preorder = preorder;
        this.mymap = new HashMap<>();
        this.index = 0;
        for(int a:inorder){
            this.mymap.put(a,index++);
        }
        this.index = 0;
        return buildTreeHelper(0,preorder.length-1);
    }
}

题解代码(Python):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def __init__(self):
        self.preorder =None
        self.mymap = {}
        self.index = 0

    def buildTreeHelper(self,left:int,right:int)->TreeNode:
        if left>right:
            return None
        root = TreeNode(self.preorder[self.index])
        self.index+=1
        root.left = self.buildTreeHelper(left,self.mymap.get(root.val)-1)
        root.right = self.buildTreeHelper(self.mymap.get(root.val)+1,right)
        return root

    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if len(preorder)==0:
            return None
        for item in inorder:
            self.mymap[item] = self.index
            self.index+=1
        self.index = 0
        self.preorder = preorder
        return self.buildTreeHelper(0,len(inorder)-1)

7.6、889. 根据前序和后序遍历构造二叉树

返回与给定的前序和后序遍历匹配的任何二叉树。
pre 和 post 遍历中的值是不同的正整数。
示例:
输入:pre = [1,2,4,5,3,6,7], post = [4,5,2,6,7,3,1]
输出:[1,2,3,4,5,6,7]
提示:
1 <= pre.length == post.length <= 30
pre[] 和 post[] 都是 1, 2, …,pre.length 的排列
每个输入保证至少有一个答案。如果有多个答案,可以返回其中一个。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析:
前序遍历第一个输出是根节点,后序遍历最后一个输出是根节点。
利用前序遍历来构建树,后序遍历来检验树是否构建完成。

创建一个节点 root,root = TreeNode(pre[preIndex])
当 root.val == post[posIndex]时, 意味着我们已经构建完毕了当前子树,如果当前子树没有构建完毕,那么我们就递归的构建左右子树。

题解代码(C++):

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int pre_idx=0,post_idx=0;
    TreeNode* constructFromPrePost(vector<int>& pre, vector<int>& post) {
        TreeNode* root = new TreeNode(pre[pre_idx++]);
        if(root->val!=post[post_idx])
            root->left = constructFromPrePost(pre,post);
        if(root->val!=post[post_idx])
            root->right = constructFromPrePost(pre,post);
        post_idx++;
        return root;
    }
};

题解代码(Java):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int preIndex = 0, posIndex = 0;
    public TreeNode constructFromPrePost(int[] pre, int[] post) {
        TreeNode root = new TreeNode(pre[preIndex++]);
        if (root.val != post[posIndex])
            root.left = constructFromPrePost(pre, post);
        if (root.val != post[posIndex])
            root.right = constructFromPrePost(pre, post);
        posIndex++;
        return root;
    }
}

题解代码(Python):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def __init__(self):
        self.preIdx = 0
        self.postIdx = 0

    def constructFromPrePost(self, pre: List[int], post: List[int]) -> TreeNode:
        root = TreeNode(pre[self.preIdx])
        self.preIdx+=1
        if root.val != post[self.postIdx]:
            root.left = self.constructFromPrePost(pre,post)
        if root.val != post[self.postIdx]:
            root.right = self.constructFromPrePost(pre,post)
        self.postIdx+=1
        return root

7.7、199. 二叉树的右视图

给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

示例:

输入: [1,2,3,null,5,null,4] 输出: [1, 3, 4]
解释:

   1            <--- 
 /   \ 
2     3         <---  
 \     \   
  5     4   <---

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-right-side-view
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析:其实就是每层选最右的一个结点,可以使用层次遍历。

题解代码(C++):

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    
    vector<int> rightSideView(TreeNode* root) {
        vector<int> res;
        if(root==NULL) return res;
        vector<vector<int>> temp;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()){
            int count = q.size();
            vector<int> v;
            while(count>0){
                TreeNode* cur = q.front();q.pop();
                v.push_back(cur->val);
                if(cur->left!=NULL) q.push(cur->left);
                if(cur->right!=NULL) q.push(cur->right);
                count--;
            }
            temp.push_back(v);
        }
        for(vector<int> v:temp){
            res.push_back(v[v.size()-1]);
        }
        return res;
    }
};

题解代码(Java):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        if(root==null) return res;
        Queue<TreeNode> q = new LinkedList<>();
        List<List<Integer>> temp = new LinkedList<List<Integer>>();
        q.offer(root);
        while(!q.isEmpty()){
            int count = q.size();
            List<Integer> v = new LinkedList<>();
            while(count>0){
                TreeNode cur = q.poll();
                v.add(cur.val);
                if(cur.left!=null) q.offer(cur.left);
                if(cur.right!=null) q.offer(cur.right);
                count--;
            }
            temp.add(v);
        }
        for(List<Integer> v:temp){
            res.add(v.get(v.size()-1));
        }
        return res;
    }
}

题解代码(Python):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def rightSideView(self, root: TreeNode) -> List[int]:
        res = []
        if root is None:
            return res
        q = []
        temp = []
        q.append(root)
        while len(q)>0:
            count = len(q)
            v = []
            while count>0:
                cur = q.pop(0)
                v.append(cur.val)
                if cur.left is not None:
                    q.append(cur.left)
                if cur.right is not None:
                    q.append(cur.right)
                count-=1
            temp.append(v)
        for v in temp:
            res.append(v[-1])
        return res

7.8、508. 出现次数最多的子树元素和

给你一个二叉树的根结点,请你找出出现次数最多的子树元素和。一个结点的「子树元素和」定义为以该结点为根的二叉树上所有结点的元素之和(包括结点本身)。

你需要返回出现次数最多的子树元素和。如果有多个元素出现的次数相同,返回所有出现次数最多的子树元素和(不限顺序)。

示例 1: 输入:

  5  
 /  \ 
2   -3 

返回 [2, -3, 4],所有的值均只出现一次,以任意顺序返回所有值。

示例 2:
输入:

  5  
 /  \ 
2   -5 

返回 [2],只有 2 出现两次,-5 只出现 1 次。

提示: 假设任意子树元素和均可以用 32 位有符号整数表示。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/most-frequent-subtree-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析:在后序遍历的过程中,不断求子树元素和,然后保存到map中记录次数,最后选择次数最多的输出即可。

题解代码(C++):

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    map<int,int> mymap;
    int dfs(TreeNode* root){
        if(root==NULL) return 0;
        int sum = dfs(root->left)+dfs(root->right)+root->val;
        if(mymap.find(sum)!=mymap.end()){
            mymap[sum]++;
        }else{
            mymap[sum] = 1;
        }
        return sum;
    }
    vector<int> findFrequentTreeSum(TreeNode* root) {
        dfs(root);
        map<int,int>::iterator it;
        int max = 0;
        for(it=mymap.begin();it!=mymap.end();it++){
            max = it->second>max?it->second:max;
        }
        vector<int> res;
        for(it=mymap.begin();it!=mymap.end();it++){
            if(it->second==max)
                res.push_back(it->first);
        }
        return res;
    }
};

题解代码(Java):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    Map<Integer,Integer> mymap = new HashMap<>();
    public int dfs(TreeNode root){
        if(root==null) return 0;
        int res = dfs(root.left)+dfs(root.right)+root.val;
        if(mymap.containsKey(res)){
            mymap.put(res,mymap.get(res)+1);
        }else{
            mymap.put(res,1);
        }
        return res;
    }
    public int[] findFrequentTreeSum(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        dfs(root);
        int max = 0;
        for(Integer val:mymap.values()){
            max = max>val?max:val;
        }
        for(Map.Entry<Integer,Integer> entry:mymap.entrySet()){
            if(entry.getValue()==max)
                res.add(entry.getKey());
        }
        int[] temp = new int[res.size()];
        int index = 0;
        for(Integer item:res){
            temp[index++] = item;
        }
        return temp;
    }
}

题解代码(Python):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def __init__(self):
        self.mymap={}

    def dfs(self,root:TreeNode)->int:
        if root is None:
            return 0
        res = self.dfs(root.left)+self.dfs(root.right)+root.val
        if self.mymap.get(res) is None:
            self.mymap[res] = 1
        else:
            self.mymap[res]+=1
        return res
    def findFrequentTreeSum(self, root: TreeNode) -> List[int]:
        self.dfs(root)
        maxNum = 0
        res = []
        for k,v in self.mymap.items():
            maxNum = maxNum if maxNum>v else v
        for k,v in self.mymap.items():
            if v==maxNum:
                res.append(k)
        return res

7.9、129. 求根到叶子节点数字之和

给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字。

例如,从根到叶子节点路径 1->2->3 代表数字 123。

计算从根到叶子节点生成的所有数字之和。

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

示例 1:

输入: [1,2,3]

  1    
 / \   
2   3 

输出: 25
解释: 从根到叶子节点路径 1->2 代表数字 12. 从根到叶子节点路径 1->3 代表数字 13. 因此,数字总和 = 12 + 13 = 25. 示例 2:

输入: [4,9,0,5,1]

     4   
    / \   
   9   0  
  / \ 
 5   1 

输出: 1026
解释: 从根到叶子节点路径 4->9->5 代表数字 495. 从根到叶子节点路径 4->9->1 代表数字491. 从根到叶子节点路径 4->0 代表数字 40. 因此,数字总和 = 495 + 491 + 40 = 1026.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sum-root-to-leaf-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析:先序遍历,一直到叶子节点,就能算出根到叶子路径的距离,然后加到结果即可。

题解代码(C++):

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int res = 0;
    void dfs(TreeNode* root,int val){
        if(root==NULL) return;
        int sum=val*10+root->val;
        if(root->left==NULL&&root->right==NULL)
            res+=sum;
        dfs(root->left,sum);
        dfs(root->right,sum);
    }
    int sumNumbers(TreeNode* root) {
        dfs(root,0);
        return res;
    }
};

题解代码(Java):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int res = 0;
    public void dfs(TreeNode root,int val){
        if(root==null) return;
        int sum = val*10+root.val;
        if(root.left==null&&root.right==null)
            res+=sum;
        dfs(root.left,sum);
        dfs(root.right,sum);
    }
    public int sumNumbers(TreeNode root) {
        dfs(root,0);
        return res;
    }
}

题解代码(Python):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def __init__(self):
        self.res = 0
    def dfs(self,root:TreeNode,val:int):
        if root is None:
            return None
        count = val*10+root.val
        if root.left is None and root.right is None:
            self.res +=count
        self.dfs(root.left,count)
        self.dfs(root.right,count)
    def sumNumbers(self, root: TreeNode) -> int:
        self.dfs(root,0)
        return self.res

7.10、951. 翻转等价二叉树

我们可以为二叉树 T 定义一个翻转操作,如下所示:选择任意节点,然后交换它的左子树和右子树。

只要经过一定次数的翻转操作后,能使 X 等于 Y,我们就称二叉树 X 翻转等价于二叉树 Y。

编写一个判断两个二叉树是否是翻转等价的函数。这些树由根节点 root1 和 root2 给出。

示例:

输入:root1 = [1,2,3,4,5,6,null,null,null,7,8], root2 =
[1,3,2,null,6,4,5,null,null,null,null,8,7] 输出:true 解释:我们翻转值为 1,3 以及 5
的三个节点。

Leetcode刷题——树篇7_第3张图片

提示:

每棵树最多有 100 个节点。 每棵树中的每个值都是唯一的、在 [0, 99] 范围内的整数。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flip-equivalent-binary-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析:因为是可以有选择地翻转某棵子树,所以需要判断是否翻转了,本质上还是判断两棵树是否相等。

题解代码(C++):

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool flipEquiv(TreeNode* root1, TreeNode* root2) {
        if(root1==NULL && root2==NULL) return true;
        if(root1==NULL && root2!=NULL) return false;
        if(root1!=NULL && root2==NULL) return false;
        if(root1->val!=root2->val) return false;
        bool isFlip = false;
    
        if(root1->left!=NULL&&root2->right!=NULL&&root1->left->val==root2->right->val) isFlip=true;
        if(root1->right!=NULL&&root2->left!=NULL&&root1->right->val==root2->left->val) isFlip=true;
        if(isFlip)
            return flipEquiv(root1->left,root2->right)&&flipEquiv(root1->right,root2->left);
        else
            return flipEquiv(root1->left,root2->left)&&flipEquiv(root1->right,root2->right);
    }
};

题解代码(Java):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean flipEquiv(TreeNode root1, TreeNode root2) {
        if(root1==null && root2==null) return true;
        if(root1!=null && root2==null) return false;
        if(root1==null && root2!=null) return false;
        if(root1.val!=root2.val) return false;
        boolean isFlip = false;
        if(root1.left!=null&&root2.right!=null&&root1.left.val==root2.right.val) isFlip=true;
        if(root1.right!=null&&root2.left!=null&&root1.right.val==root2.left.val) isFlip=true;
        if(isFlip)
            return flipEquiv(root1.left,root2.right)&&flipEquiv(root1.right,root2.left);
        else
            return flipEquiv(root1.left,root2.left)&&flipEquiv(root1.right,root2.right);
    }
}

题解代码(Python):

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def flipEquiv(self, root1: TreeNode, root2: TreeNode) -> bool:
        if root1 is None and root2 is None:
            return True
        if root1 is not None and root2 is None:
            return False
        if root1 is None and root2 is not None:
            return False
        if root1.val != root2.val:
            return False
        isFlip = False
        if root1.left is not None and root2.right is not None and root1.left.val == root2.right.val:
            isFlip=True
        if root1.right is not None and root2.left is not None and root1.right.val == root2.left.val:
            isFlip= True
        if isFlip:
            return self.flipEquiv(root1.left,root2.right) and self.flipEquiv(root1.right,root2.left)
        else:
            return self.flipEquiv(root1.left,root2.left) and self.flipEquiv(root1.right,root2.right)

你可能感兴趣的:(刷题打基础系列)