LeetCode刷题(二十二)-----树-------medium部分(Java、C++)

102. 二叉树的层次遍历

给定一个二叉树,返回其按层次遍历的节点值。(即逐层地,从左到右访问所有节点)。
例如:给定二叉树:[3,9,20,null,null,15,7],

在这里插入图片描述
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]

思路一:
如何遍历一棵树

有两种通用的遍历树的策略:
深度优先搜索(DFS)

在这个策略中,我们采用深度作为优先级,以便从根开始一直到达某个确定的叶子,然后再返回根到达另一个分支。

深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为先序遍历,中序遍历和后序遍历。

宽度优先搜索(BFS)

我们按照高度顺序一层一层的访问整棵树,高层次的节点将会比低层次的节点先被访问到。

下图中的顶点按照访问的顺序编号,按照1-2-3-4-5的顺序来比较不同的策略。

作者:LeetCode
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-ci-bian-li-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

116. 填充每个节点的下一个右侧节点指针

给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
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 所示。

思路一:拉拉链解法
在这里插入图片描述
我的:

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

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/
class Solution {
public:
    Node* connect(Node* root) 
    {
        if(!root)
        {
            return NULL;
        }    
        Node* left = root -> left;
        Node* right = root -> right; 
        while(left)
        {
            left -> next = right;
            left = left -> right;
            right = right -> left;
        }
        connect(root -> left);
        connect(root -> right);
        return root;
    }
};

98. 验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:

在这里插入图片描述
示例2:
在这里插入图片描述
思路一:
直觉
乍一看,这是一个平凡的问题。只需要遍历整棵树,检查 node.right.val > node.val 和node.left.val < node.val 对每个结点是否成立。
在这里插入图片描述
问题是,这种方法并不总是正确。不仅右子结点要大于该节点,整个右子树的元素都应该大于该节点。例如:
在这里插入图片描述
这意味着我们需要在遍历树的同时保留结点的上界与下界,在比较时不仅比较子结点的值,也要与上下界比较。
方法一: 递归
上述思路可以用递归法实现。首先将结点的值与上界和下界(如果有)比较。然后,对左子树和右子树递归进行该过程。
在这里插入图片描述
复杂度分析
• 时间复杂度 : O(N)。每个结点访问一次。
• 空间复杂度 : O(N)。我们跟进了整棵树。
方法二: 迭代
通过使用栈,上面的递归法可以转化为迭代法。这里使用深度优先搜索,比广度优先搜索要快一些。
在这里插入图片描述
复杂度分析
• 时间复杂度 : O(N)。每个结点访问一次。
• 空间复杂度 : O(N)。我们跟进了整棵树。

作者:LeetCode
链接:https://leetcode-cn.com/problems/validate-binary-search-tree/solution/yan-zheng-er-cha-sou-suo-shu-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我的:

/**
 * 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 isValidBST(TreeNode* root) {
        return helper(root,LONG_MIN,LONG_MAX);
    }
    bool helper(TreeNode* cur,long lt,long rt){
        if(cur==NULL) return true;
        if(cur->val<=lt||cur->val>=rt) return false;
        if(helper(cur->left,lt,cur->val)&&helper(cur->right,cur->val,rt)) return true;
        return false;
    }

};


发布了47 篇原创文章 · 获赞 21 · 访问量 7214

猜你喜欢

转载自blog.csdn.net/qq_18315295/article/details/103863848