分类 树 下的文章

填充每个节点的下一个右侧节点指针/填充每个节点的下一个右侧节点指针 II

问题描述

给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL

示例:

输入:{"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":null,"right":null,"val":4},"next":null,"right":{"$id":"4","left":null,"next":null,"right":null,"val":5},"val":2},"next":null,"right":{"$id":"5","left":{"$id":"6","left":null,"next":null,"right":null,"val":6},"next":null,"right":{"$id":"7","left":null,"next":null,"right":null,"val":7},"val":3},"val":1}

输出:{"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":{"$id":"4","left":null,"next":{"$id":"5","left":null,"next":{"$id":"6","left":null,"next":null,"right":null,"val":7},"right":null,"val":6},"right":null,"val":5},"right":null,"val":4},"next":{"$id":"7","left":{"$ref":"5"},"next":null,"right":{"$ref":"6"},"val":3},"right":{"$ref":"4"},"val":2},"next":null,"right":{"$ref":"7"},"val":1}

解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。

提示:
你只能使用常量级额外空间。
使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node

思路

  • 将二叉树按层存储到 vector<Node*> res中,我用的是深搜。详情可以见 https://www.irene.ink/archives/77/
  • 然后,除每层的最后一个节点外,让每个节点res[i][j]的next指向res[i][j+1],最后一个节点res[i][res[i].size()-1]的next指向nullptr;
  • 最后,返回根节点root即可。

题解

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() {}

    Node(int _val, Node* _left, Node* _right, Node* _next) {
        val = _val;
        left = _left;
        right = _right;
        next = _next;
    }
};
*/
class Solution {
public:
    vector<vector<Node *>> res;
    Node *connect(Node *root) {
        if(root== nullptr)
            return root;
        dfs(root,0);
        for(int i=0;i<res.size();i++){
            for(int j=0;j<res[i].size()-1;j++){
                res[i][j]->next=res[i][j+1];
            }
            res[i][res[i].size()-1]->next= nullptr;
        }
        return root;
    }
    void dfs(Node *node,int dep){
        if(node== nullptr) return;
        if(dep+1>res.size()) res.push_back(vector<Node *>{});
        res[dep].push_back(node);
        if(node->left!= nullptr) dfs(node->left,dep+1);
        if(node->right!= nullptr) dfs(node->right,dep+1);
    }
};

二叉树的锯齿形层次遍历

问题描述

给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

例如:
给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回锯齿形层次遍历如下:

[
  [3],
  [20,9],
  [15,7]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal

思路

题解

class Solution {
public:
    vector<vector<int>> ret;
    vector<vector<int>> zigzagLevelOrder(TreeNode *root) {
        dfs(root, 0);
        int n=ret.size();
        for(int i=0;i<n;i++){
            if(i%2!=0){
                reverse(ret[i].begin(),ret[i].end());
            }
        }
           return ret; 
    }
    void dfs(TreeNode *node, int level) {
        if (node == nullptr) return;
        if (level + 1 > ret.size()) ret.push_back(vector<int>());
        ret[level].push_back(node->val);
        if (node->left != nullptr)dfs(node->left, level + 1);
        if (node->right != nullptr) dfs(node->right, level + 1);
    }
};

不同的二叉搜索树

问题描述

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

示例:

输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-binary-search-trees

思路

由i个不同数字组成的二叉搜索树的数量,只与数字的数量i有关,与数的大小无关。
dp[i]代表n个节点数的树的种数。dp[0]、dp[1]均为1;
求n个节点构成的树的种类时,for(int j=1;j<=i;j++){dp[i]+=dp[j-1]*dp[i-j];},表示根节点为1
的时候树的种类加上根节点为2...一直加到根节点为n的树的种类。
外层循环for(int i=2;i<=n;i++)为了求出每次的dp[j-1]*dp[i-j]。

题解

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

先序遍历构造二叉树

问题描述

返回与给定先序遍历 preorder 相匹配的二叉搜索树(binary search tree)的根结点。
(回想一下,二叉搜索树是二叉树的一种,其每个节点都满足以下规则,对于 node.left 的任何后代,值总 < node.val,而 node.right 的任何后代,值总 > node.val。此外,先序遍历首先显示节点的值,然后遍历 node.left,接着遍历 node.right。)

示例:
输入:[8,5,1,7,10,12]
输出:[8,5,10,1,7,null,12]
1266.png

提示:
1 <= preorder.length <= 100
先序 preorder 中的值是不同的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-search-tree-from-preorder-traversal

思路

题解

最大二叉树

问题描述

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
二叉树的根是数组中的最大元素。
左子树是通过数组中最大值左边部分构造出的最大二叉树。
右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。
Example 1:

输入: [3,2,1,6,0,5]
输入: 返回下面这棵树的根节点:

      6
    /   \
   3     5
    \    / 
     2  0   
       \
        1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
注意:
给定的数组的大小在 [1, 1000] 之间。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-binary-tree

思路

题解