二叉树递归-深度优先搜索

###[二叉树的最近公共祖先](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree)

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

示例 1:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1

输出:3

解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

示例 2:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4

输出:5

解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

示例 3:

输入:root = [1,2], p = 1, q = 2

输出:1

提示:

树中节点数目在范围 [2, 105] 内。

-109 <= Node.val <= 109

所有 Node.val 互不相同 。

p != q

p 和 q 均存在于给定的二叉树中。

class Solution {

public:

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)

{

if (!root || root == p|| root == q) return root;

//往下找点判断

TreeNode* left = lowestCommonAncestor(root->left,p,q);

TreeNode* right = lowestCommonAncestor(root->right,p,q);

if (left && right) return root;

return left ? left:right;

}

};

###[二叉树的最小深度](https://leetcode-cn.com/problems/minimum-depth-of-binary-tree)

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

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

示例 1:

输入:root = [3,9,20,null,null,15,7]

输出:2

示例 2:

输入:root = [2,null,3,null,4,null,5,null,6]

输出:5

提示:

树中节点数的范围在 [0, 105] 内

-1000 <= Node.val <= 1000

二叉树状态计算用的递归

class Solution {

public:

int minDepth(TreeNode* root) {

if (!root)return 0;

if (!root->left)return minDepth(root->right) + 1;

if (!root->right)return minDepth(root->left) + 1;

return min(minDepth(root->left),minDepth(root->right)) + 1;

}

};

###[路径总和 III](https://leetcode-cn.com/problems/path-sum-iii)

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

示例 1:

输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8

输出:3

解释:和等于 8 的路径有 3 条,如图所示。

示例 2:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22

输出:3

提示:

二叉树的节点个数的范围是 [0,1000]

-109 <= Node.val <= 109

-1000 <= targetSum <= 1000

给定一个二叉树,它的每个结点都存放着一个整数值。

找出路径和等于给定数值的路径总数。

路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

class Solution {

public:

int pathSum(TreeNode* root, int sum) {//本节点或者左右节点开始找

if (!root) return 0;

int res = findPath(root, 0, sum) + pathSum(root->left, sum) + pathSum(root->right, sum);

return res;

}

int findPath(TreeNode* node, int curSum, int sum) {//递归找符合需求路径

if (!node) return 0;

curSum += node->val;

return (curSum==sum)+findPath(node->left, curSum, sum) + findPath(node->right,curSum, sum);

}

};

###[二叉树的中序遍历](https://leetcode-cn.com/problems/binary-tree-inorder-traversal)

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

示例 1:

输入:root = [1,null,2,3]

输出:[1,3,2]

示例 2:

输入:root = []

输出:[]

示例 3:

输入:root = [1]

输出:[1]

提示:

树中节点数目在范围 [0, 100] 内

-100 <= Node.val <= 100

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

class Solution {

public:

vector<int> inorderTraversal(TreeNode* root) {

if (!root)return {};

vector<int> res;

stack<TreeNode*> sk;

TreeNode* p = root;

while(p||sk.size())

{

while (p)

{

sk.push(p);

p = p->left;

}

p = sk.top();

sk.pop();

res.push_back(p->val);//访问

p = p->right;

}

return res;

}

};

递归

class Solution {

public:

vector<int> inorderTraversal(TreeNode* root) {

vector<int> res;

inorder(root,res);

return res;

}

void inorder(TreeNode* root,vector<int>& output) {

if (root != nullptr) {

inorder(root->left, output);

output.push_back(root->val);

inorder(root->right, output);

}

}

};

###[二叉树的后序遍历](https://leetcode-cn.com/problems/binary-tree-postorder-traversal)

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。

示例 1:

输入:root = [1,null,2,3]

输出:[3,2,1]

示例 2:

输入:root = []

输出:[]

示例 3:

输入:root = [1]

输出:[1]

提示:

树中节点的数目在范围 [0, 100] 内

-100 <= Node.val <= 100

进阶:递归算法很简单,你可以通过迭代算法完成吗?

递归

class Solution {

public:

vector<int> postorderTraversal(TreeNode* root) {

vector<int> res;

postorder(root,res);

return res;

}

void postorder(TreeNode* root,vector<int>& output) {

if (root != nullptr) {

postorder(root->left, output);

postorder(root->right, output);

output.push_back(root->val);

}

}

};

这里附加压栈迭代法

class Solution {

public:

vector<int> postorderTraversal(TreeNode* root)

{

if (!root)return {};

TreeNode* p = root;

vector<int> res;

stack<TreeNode*> s;

while(p || s.size())

{

while(p)

{

res.push_back(p->val);//先序

s.push(p);

p = p->right;//跟先序的相反

}

p = s.top();

s.pop();

p = p->left;//跟先序的相反

}

reverse(res.begin(),res.end());//反序

return res;

}

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值