题目描述:
给定一个二叉树的 根节点 root
,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
样例1:
输入: root = [2,1,3] 输出: 1
样例2:
输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7
来源:力扣(LeetCode)
链接:力扣
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
看了力扣题解区各路大佬八仙过海各显神通的巧妙解法,却只能知其然而不知其所以然的弱鸡愤懑的关闭了题解,决心自己用暴力模拟的手段强行破题
本题解采用非常亲民的易于理解的暴力破解方式,使用了顺序栈存储,对树进行先序遍历,对树中每个节点的高度、值详细询问,每当遇到条件优于当前最佳答案的节点,就对其进行存储,以供后续比对及最终返回。最后在遍历完整棵树后返回最佳答案节点的值。
具体代码:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
type stark struct{ // 定义一个栈
data []*TreeNode // 用于存储树中的节点
deep []int // 用于存储对应节点的高度
top int // 用于记录栈顶位置
}
func findBottomLeftValue(root *TreeNode) int {
var S stark // 定义栈S供后续使用
var p = root // 定义一个树节点指针,用于访问树中节点
max := 0 // 用于记录当前最佳答案的高度
pr := p // 用于记录当前最佳答案节点
// 栈S的初始化
S.top = -1
S.data = make([]*TreeNode,10000)
S.deep = make([]int,10000) // 分别为树节点指针存储树组、对应高度存储树组申请空间
// 将树的总根节点入栈,以供后续遍历操作
S.top += 1
S.data[S.top] = root
S.deep[S.top] = 0
// 本代码核心部分,真正用于求解最佳答案的部分
// 整体使用先序遍历
for S.top > -1{ // 当栈非空,继续遍历
for p.Left != nil{ // 当左子树存在,则循环访问当前节点左子树,直到左子树左孩子节点为空
p = p.Left
S.top += 1
S.deep[S.top] = S.deep[S.top - 1] + 1 // 每向下访问一次,则当前深度加一
S.data[S.top] = p
if max < S.deep[S.top]{ // 若当前节点高度大于当前最佳答案高度,则记录当前节点
max = S.deep[S.top]
pr = p
}
}
// 当遍历完左子树,则向上回溯,直到一个拥有右子树的节点,停止回溯
for S.data[S.top].Right == nil{
S.top -= 1 // 每向上回溯一层,则出栈一个元素
if S.top <= -1{ // 若当前整棵树的节点已经遍历完,则退出循环
break
}
// p = S.data[S.top] (冗余代码,不做理会)
}
if S.top <= -1{ // 若当前整棵树的节点已经遍历完,则退出循环
break
}else{
p = S.data[S.top].Right // 进入当前栈顶节点的右子树,开始其右子树的遍历
// 进入当前节点右子树,因当前节点已完全访问,故直接用其右孩子节点覆盖当前节点在栈中位置
S.deep[S.top] += 1 // 用右孩子节点覆盖当前节点在栈中位置,故对应高度加一
S.data[S.top] = p
if max < S.deep[S.top]{ // 若当前节点高度大于当前最佳答案高度,则记录当前节点
max = S.deep[S.top]
pr = p
}
}
}
return pr.Val // 返回最佳答案节点的值
}
勉强过关www