【刷题日记】树的那些事儿(二)——花式递归

热身递归

求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)
思路
不让乘除咋搞。。。自己调算自己吧。。。

def sumThem(n):
	if n ==0 or n==1:
		return n
	return n+sumThem(n-1)

树的镜像

题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。

def Mirror(root):
	# 不是树或者只有根
	if not root or not (root.left or root.right)return root
	# 交换左右子树
	root.left,root.right = root.right,root.left
	if root.left:
		root.left = Mirror(root.left)
	if root.right:
		root.right = Mirror(root.right)
	return root

树的子结构

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        def isSubTree(root1,root2):
    		if not root2:
    			return True
    		if not root1 or (root1.val!=root2.val):
    			return False
    		return isSubTree(root1.left,root2.left) and isSubTree(root1.right,root2.right)
    	if not pRoot1 or not pRoot2:
    		return False
    	return isSubTree(pRoot1,pRoot2) or isSubTree(pRoot1.left,pRoot2) or isSubTree(pRoot1.right,pRoot2)	

树的深度

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

思路
这个要是不会写,树就是白学了。真的

def TreeDepth(root):
	# 树空了时深度为0
	if not root:
		return 0
	# 递归求左右子树的深度
	left = TreeDepth(root.left)
	right = TreeDepth(root.right)
	# 树的深度是左右子树的较大值+根
	return max(left,right)+1

树的深度进阶———平衡二叉树

输入一棵二叉树,判断该二叉树是否是平衡二叉树。

平衡二叉树左右子树高度差不超过1

class Solution:
    def IsBalanced_Solution(self, pRoot):
        # write code here
        if not pRoot:
            return True
        if abs(self.Depth(pRoot.left)-self.Depth(pRoot.right))>1:
            return False
        return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
    def Depth(self,pRoot):
        if not pRoot:
            return 0
        return max(self.Depth(pRoot.left),self.Depth(pRoot.right))+1

树的深度进阶——二叉树的直径(leetcode543)

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。

示例 :
给定二叉树

      1
     / \
    2   3
   / \     
  4   5    

返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。

注意:两结点之间的路径长度是以它们之间边的数目表示。

思路
递归遍历,借助树高度
对于每一个当前节点,选择左、右节点中最大的长度,然后加上1(当前路径),则是当前的最长路径深度
对于直径,全局变量dia为直径,每次取左、右节点深度的和。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def diameterOfBinaryTree(self, root):
        if not root:
            return 0
        # 直径
        self.dia = 0
        
        def diameter(node):
            if not node:
                return 0
            # 左子树最长路径深度
            l = diameter(node.left)
            # 右子树最长路径深度
            r = diameter(node.right)
            # 更新路径和
            self.dia = max(l+r,self.dia)
            # 最长深度
            return max(l,r)+1
        
        diameter(root)
        
        return self.dia

给定结点的下一个结点

  1. 返回给定结点的中序遍历的下一个结点
    思路
    首先:
    中序遍历:左-根-右
    对于给定的结点:
    (1) 有右子树: 下一个结点是右子树的最左结点
    (2) 没有右子树:
    a. 父节点为空: 该结点是树根,没有下一个结点
    b. 父节点不空:
    从当前结点开始向上回溯,直到回溯结点为父亲的左孩子,返回父亲
    (3)其他情况返回None(当前结点为最后一个结点)
class Solution:
    def GetNext(self, pNode):
    	if not pNode:
    		return None
    	if pNode.right:
    		pNode =pNode.right
    		while pNode.left:
    			pNode = pNode.left
    		return pNode
    	else:
    		while pNode.next:
    			father = pNode.next
	    		if father.left == pNode:
    				return father
    			pNode = father
    	return None

二叉树的路径和为某一值

class Solution:
    # 返回二维列表,内部每个列表表示找到的路径
    def FindPath(self, root, expectNumber):
    	# 递归终止条件:
    	# 1. 树遍历完也没有达到期望值
    	if not root:
    		return []
    	# 2. 没有左右子树且值为期望值
    	if not root.left and not root.right:
    		if root.val == expectNumber:
    			return [[root.val]]
    		# 以下两行其实可以没有
    		else:
    			return []
    	# 递归查找
    	left_path = self.FindPath(root.left, expectNumber - root.val)
    	right_path = self.FindPath(root.right,expectNumber - root.val)
		path =[]
		for item in left_path+right_path:
			path.apppend([root.val]+item)
		return path
    	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值