513.找树左下角的值
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给定一个二叉树的 根节点 root
,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
输入: root = [2,1,3] 输出: 1
解题思路:
- 使用层遍历,能使得每层的参数,按照从左到右的顺序进行存储。因此,很容易获得最后一层的最左边的节点值。在方法中创建总表用来收纳每层。在第一层循环中创建层表,用来收纳每层的参数。
- 使用前序递归法。前序递归法由于其特性中左右进行遍历,很容易解出这道题。设置Deep当作旗子。当第一个下一层的深度必然是大于Deep的值,收集此值,并且将此深度赋值给Deep。从而保证后面的参数并不会被收纳。
层遍历迭代法:
public class Solution {
public int FindBottomLeftValue(TreeNode root) {
List<List<int>> ll1 = new List<List<int>>();
Queue<TreeNode> q1 = new Queue<TreeNode>();
q1.Enqueue(root);
while(q1.Count > 0){
int len = q1.Count;
List<int> l1 = new List<int>();
while(len > 0){
TreeNode temp = q1.Dequeue();
l1.Add(temp.val);
if(temp.left != null)q1.Enqueue(temp.left);
if(temp.right != null)q1.Enqueue(temp.right);
len--;
}
ll1.Add(l1);
}
List<int> res = ll1[ll1.Count-1];
return res[0];
}
}
前序递归法:
public class Solution {
int maxDepth = int.MinValue;
int res;
public int FindBottomLeftValue(TreeNode root) {
Traversal(root,0);
return res;
}
public void Traversal(TreeNode root,int depth){
if(root.left == null && root.right == null){
if(depth > maxDepth){
maxDepth = depth;
res = root.val;
}
return;
}
if(root.left != null){
depth++;
Traversal(root.left,depth);
depth--;
}
if(root.right != null){
depth++;
Traversal(root.right,depth);
depth--;
}
//return;
}
}
112路径总和
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给你二叉树的根节点 root
和一个表示目标和的整数 targetSum
。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum
。如果存在,返回 true
;否则,返回 false
。
叶子节点 是指没有子节点的节点。
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 输出:true 解释:等于目标和的根节点到叶节点路径如上图所示。
解题思路:
- 前序递归法。使用标记和表。通过表来收纳每条路径的值,当到达路径末端的时候,将其相加与目标值进行对比,符合则让标记为true。每当运算一个函数,则在末尾进行表的删减,表示路径弹出末尾节点值。
递归法:
public class Solution {
List<int> l1 = new List<int>();
bool Flag = false;
public bool HasPathSum(TreeNode root, int targetSum) {
GetSum(root,targetSum);
return Flag;
}
public void GetSum(TreeNode root,int targetSum){
if(root == null) return;
l1.Add(root.val);
if(root.left == null && root.right == null){
int res = 0;
foreach(int item in l1){
res = res + item;
}
if(res == targetSum){
Flag = true;
}
}
GetSum(root.left,targetSum);
GetSum(root.right,targetSum);
l1.RemoveAt(l1.Count-1);
}
}
113.路径总和Ⅱ
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给你二叉树的根节点 root
和一个整数目标和 targetSum
,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 输出:[[5,4,11,2],[5,8,4,5]]
解题思路:
- 与112基本无差。唯一要注意的是,IList<IList<int>>添加的元素是List<int>。因此,每次添加的时候都需要new一个新的出来,并将path的值赋给这个,然后再被添加到二维数组表中。(c#语言特性)
递归法:
public class Solution {
IList<int> path = new List<int>();
IList<IList<int>> ll1;
public IList<IList<int>> PathSum(TreeNode root, int targetSum) {
ll1 = new List<IList<int>>();
GetSum(root,targetSum,ll1);
return ll1;
}
public void GetSum(TreeNode root,int targetSum,IList<IList<int>> ll1){
if(root == null) return;
path.Add(root.val);
if(root.left == null && root.right == null){
int res = 0;
foreach(int item in path){
res = res + item;
}
//Console.WriteLine(res);
if(res == targetSum){
ll1.Add(new List<int>(path));
//Console.WriteLine(ll1.Count);
}
}
GetSum(root.left,targetSum,ll1);
GetSum(root.right,targetSum,ll1);
path.RemoveAt(path.Count-1);
}
}
106.从中序与后序遍历序列构造二叉树
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给定两个整数数组 inorder
和 postorder
,其中 inorder
是二叉树的中序遍历, postorder
是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3] 输出:[3,9,20,null,null,15,7]
解题思路:
- 核心思路是,通过后序确定中节点。然后获取该中节点在中序中的位置。该中节点之前为左,之后为右。重复将左边,和右边分别放到递归函数中,构造二叉树。
- 难点,递归的终止条件。对中序来说,每次递归,都会缩小长度,因此当左边大于等于右边的时候则为空,或者对于后序来说,左边大于等于右边时,则为空。
递归解法:
public class Solution {
Dictionary<int,int> dic;
public TreeNode BuildTree(int[] inorder, int[] postorder) {
dic = new Dictionary<int,int>();
for(int i = 0;i < inorder.Length;i++){
dic.Add(inorder[i],i);
}
return findNode(inorder,0,inorder.Length,postorder,0,postorder.Length);
}
public TreeNode findNode(int[] inorder,int inBegin,int inEnd,int[] postorder,int postBegin,int postEnd){
if(inBegin >= inEnd || postBegin >= postEnd){
return null;
}
int rootIndex = dic[postorder[postEnd-1]];//获取切割的中节点位置
TreeNode root = new TreeNode(inorder[rootIndex]);//构造节点
int lenOfLeft = rootIndex - inBegin;
root.left = findNode(inorder,inBegin,rootIndex,postorder,
postBegin,postBegin+lenOfLeft);
root.right = findNode(inorder,rootIndex + 1,inEnd,
postorder,postBegin + lenOfLeft,postEnd-1);
return root;
}
}