目录
一、翻转二叉树
题目:翻转二叉树
思路:直接用前序或者后续遍历,挨个儿反转就行了。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func invertTree(root *TreeNode) *TreeNode {
if root == nil {
return nil
}
temp := root.Left
root.Left = root.Right
root.Right = temp
invertTree(root.Left)
invertTree(root.Right)
return root
}
二、对称二叉树
题目:对称二叉树
思路:利用递归,去遍历根节点左右孩子的节点,之后进行比较。但是他说的镜像对称,不是对比是否一样,所以左右两棵子树遍历的先后顺序是不同的。
层次遍历这道题也是ok的,就是左子树从左向右,右子树从右往左。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isSymmetric(root *TreeNode) bool {
return preOrderTwo(root.Left,root.Right)
}
func preOrderTwo (l *TreeNode,r *TreeNode) bool {
if l == nil && r == nil {
return true
}
if l == nil || r == nil {
return false
}
if l.Val != r.Val {
return false
}
lBool := preOrderTwo(l.Right,r.Left)
rBool := preOrderTwo(l.Left,r.Right)
return lBool && rBool
}
层次遍历方法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
if not root or (root.left == None and root.right == None):
return True
leftStack = list()
rightStack = list()
leftStack.append(root.left)
rightStack.append(root.right)
while leftStack and rightStack:
l = leftStack.pop()
r = rightStack.pop()
if l != None and r != None:
if l.val != r.val:
return False
leftStack.append(l.right)
leftStack.append(l.left)
rightStack.append(r.left)
rightStack.append(r.right)
elif l == None and r == None:
continue
else:
return False
return True
三、二叉树的最大深度
题目:二叉树的最大深度
思路;利用递归遍历,分别记录下左右子树的最大深度,当前节点的最大深度是左右子树中深度比较大的中的一个再加一就是当前节点的最大深度。
func maxDepth(root *TreeNode) int {
if root == nil {
return 0
}
l := maxDepth(root.Left)
r := maxDepth(root.Right)
max := l
if max < r {
max = r
}
return max+1
}
四、二叉树的最小深度
题目:二叉树的最小深度
思路:其实和最大深度是一个思路,只不过有个问题需要考虑下,就是加入这颗树只有右子树,他的最小深度可能是节点个数,而不是0.
func minDepth(root *TreeNode) int {
if root == nil {
return 0
}
l := minDepth(root.Left)
r := minDepth(root.Right)
//防止出现只有一个孩子的时候的误判
if l == 0 {
return r + 1
}
if r == 0 {
return l + 1
}
min := l
if min > r {
min = r
}
return min+1
}
五、完全二叉树的节点个数
思路:两个思路,第一个是直接求树种节点的个数。
第二个思路用到了满二叉树的性质。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
//正常写法
func countNodes(root *TreeNode) int {
if root == nil {
return 0
}
l := countNodes(root.Left)
r := countNodes(root.Right)
return l + r + 1
}
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
//利用满二叉树的性质
func countNodes(root *TreeNode) int {
if root == nil {
return 0
}
lHigh,rHigh := 0,0
lptr,rptr := root,root
for lptr.Left != nil {
lptr = lptr.Left
lHigh++
}
for rptr.Right != nil {
rptr = rptr.Right
rHigh++
}
if rHigh == lHigh {
return (2 << lHigh) - 1
}
l := countNodes(root.Left)
r := countNodes(root.Right)
return l + r + 1
}
六:平衡二叉树
题目:平衡二叉树
思路,利用求二叉树深度的方式计算左右孩子深度是多少,计算完深度之后计算两者的差值,一旦差值大于1,就不用再进行遍历了。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isBalanced(root *TreeNode) bool {
if root == nil {
return true
}
depth := depth(root)
if depth == -1 {
return false
}
return true
}
//其实可以理解成,在求树的的深度的同时,计算改子树是不是平衡二叉树
func depth(root *TreeNode) int {
if root == nil {
return 0
}
l := depth(root.Left)
if l == -1 {
return -1
}
r := depth(root.Right)
if r == -1 {
return -1
}
if math.Abs(float64(l - r)) > 1 {
return -1
}
max := l
if max < r {
max = r
}
return max + 1
}
七、二叉树的所有路径
思路:就是利用先序遍历完成的,其中回涉及到遍历回溯的问题
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func binaryTreePaths(root *TreeNode) []string {
res := make([]string,0)
preOrder(root,&res,"")
return res
}
func preOrder(root *TreeNode,res *[]string,route string) {
if root == nil {//说明访问到根节点了
return
}
if root.Left == nil && root.Right == nil {
route = route + strconv.Itoa(root.Val)
*res = append(*res,route)
return
}
route = route + strconv.Itoa(root.Val) + "->"
preOrder(root.Left,res,route)
preOrder(root.Right,res,route)
}
八、左叶子之和
思路:遍历过程中传一个参数就是flag,用来判断是否从左子树过来的。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func sumOfLeftLeaves(root *TreeNode) int {
res := 0
preOrder(root,&res,false)
return res
}
func preOrder(root *TreeNode,res *int,flag bool) {
if root.Left == nil && root.Right == nil && flag {
*res = *res + root.Val
return
}
if root.Left != nil {
preOrder(root.Left,res,true)
}
if root.Right != nil {
preOrder(root.Right,res,false)
}
}
九、找树左下角的值
题目:找树左下角的值
思路:利用层次遍历或者递归遍历都行,目的就是为了找到层次数最大的,并且第一个出现在遍历顺序中的节点。
递归法:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
var maxDeep = -1
func findBottomLeftValue(root *TreeNode) int {
if root.Left==nil&&root.Right==nil{//需要提前判断一下(不要这个if的话提交结果会出错,但执行代码不会。防止这种情况出现,故先判断是否只有一个节点)
return root.Val
}
res := 0
deepth(root,&res,0)
return res
}
func deepth(root *TreeNode,res *int,deep int) {
if root.Left == nil && root.Right == nil && deep > maxDeep {
*res = root.Val
maxDeep = deep
return
}
if root.Left != nil {
deep++
deepth(root.Left,res,deep)
deep--
}
if root.Right != nil {
deep++
deepth(root.Right,res,deep)
deep--
}
}
层次法:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func findBottomLeftValue(root *TreeNode) int {
l := list.New()//层次遍历队列
curlen := 1
nextlen := 0
l.PushBack(root)
res := root.Val
for l.Len() > 0 {
ptr := l.Remove(l.Front()).(*TreeNode)
curlen--
if ptr.Left != nil {
l.PushBack(ptr.Left)
nextlen++
}
if ptr.Right != nil {
l.PushBack(ptr.Right)
nextlen++
}
if curlen == 0{
if l.Len() > 0 {
p := l.Front().Value.(*TreeNode)
res = p.Val
}
curlen = nextlen
nextlen = 0
}
}
return res
}