上周看了同学的学习笔记,发现自己写的笔记真的敷衍。。所以决定从这周开始重新做人!认真记笔记,每天学习完就把笔记记下来,这样每周还能轻松一两天。
正文开始
100、相同的树:给定两个二叉树,编写一个函数来检验它们是否相同(两个树的结构相同并且节点上的值相同,则认为它们是相同的)。
二叉树的概念在之前C语言版的数据结构里学过,这次还是想先用Python来实现一下,从之前做链表那道题就觉得对Python的一些数据结构语法不是很会用,这次看了树好像更明白了一点:.val表示某一节点上的值。这道题的解法中用了递归的思想,逻辑很好理解并且运行时间也不长。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSameTree(self, p, q):
"""
:type p: TreeNode
:type q: TreeNode
:rtype: bool
"""
if not p and not q:
return True
if p and q and p.val==q.val:
l=self.isSameTree(p.left,q.left)
r=self.isSameTree(p.right,q.right)
return l and r
else:
return False
101、对称二叉树:给定一个二叉树,检查它是否是镜像对称的。
因为刚做完100题所以看到这道题很自然的想到上面那个判断两个二叉树是否相等的函数。将给定二叉树的根结点的左右结点看做两个二叉树,判断是否相同,不过递归时要注意变成左子树的左结点和右子树的右结点进行判断,代码如下:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetric(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
def isSameTree(p,q):
if not p and not q:
return True
if p and q and p.val==q.val:
l=isSameTree(p.left,q.right)
r=isSameTree(p.right,q.left)
return l and r
else:
return False
if not root:
return True
else:
return isSameTree(root.left,root.right)
不过这个代码运行时间较长,想再试一下迭代的方法。
104、二叉树的最大深度:给定一个二叉树,找出其最大深度(二叉树的深度为根结点到最远叶子节点的最长路径上的节点个数)。
首先想到的是while循环,用i来累加表示经过的节点个数,当一层的右节点的左右节点都为空时循环结束,
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
else:
i=1
while root.left or root.right:
if root.left and (root.left.left or root.left.right):
root=root.left
i+=1
else:
root=root.right
i+=1
return i
本来写的代码是这样的,然后执行时报错是说root.left.left这样的写法错误,因为上面定义时root.left的类型是None.
然后百度了一下别人的思路,发现依旧可以使用递归的思想!
if not root:
return 0
else:
l=1+self.maxDepth(root.left)
r=1+self.maxDepth(root.right)
return max(l,r)
这样就很简单了,看来还是递归用的不够熟练。。
107、二叉树的层次遍历:给定一个二叉树,返回其节点值自底向上的层次遍历(即按从叶子节点所在层到根节点所在层,逐层从左到右遍历)
自己想写出来无奈尝试了好久没有结果╮(╯▽╰)╭,于是百度。
对二叉树的层次遍历是通过队列完成的,即Python中的queue模块(之前没有听过这个模块)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrderBottom(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
from queue import Queue
result=[]
if not root:
return result
else:
q=Queue()#创建队列q
q.put(root)
while not q.empty():
size=q.qsize()#使用size获取每层的队列大小
temp_list=[]
while size>0:
temp_node=q.get()#内层循环获取头结点
temp_list.append(temp_node.val)
if temp_node.left !=None:
q.put(temp_node.left)
if temp_node.right!=None:
q.put(temp_node.right)
size-=1
result.append(temp_list)
result.reverse()
return result
这种方法好像运行时间过长,and不是很熟悉这种语法,然后查到了另一种用list结构,用两个list分别存储当前父节点和当前父节点的所有孩子,通过不断更新父节点list,达到层次遍历的目的。另外,用一个list存储每一层的节点值,用于返回。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def levelOrderBottom(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if root == None :
return [] #如果根节点为空,则返回空链表
else :
node_value_result = [[root.val]] #node_value_result 记录从叶节点开始层次遍历的各节点的节点值
ancestors = [root] #ancestors记录当前层的父节点,依次遍历,寻找每个当前父节点的孩子节点
while len(ancestors) != 0 : #如果当前父节点为空,退出
temp_node_value = [] #否则,temp_node_value 记录当前所有父节点的孩子节点的值
next_ancestors = [] #next_ancestors 记录当前所有父节点的孩子节点,到下一次循环,这些节点变成父节点
for i in range(len(ancestors)) : #依次 遍历每个父节点
if ancestors[i].left != None : #访问左孩子
temp_node_value.append(ancestors[i].left.val)
next_ancestors.append(ancestors[i].left)
if ancestors[i].right != None : #访问右孩子
temp_node_value.append(ancestors[i].right.val)
next_ancestors.append(ancestors[i].right)
if len(temp_node_value) != 0 : #如果孩子节点值不为空,插入到result中,用于返回
node_value_result.append(temp_node_value)
ancestors = next_ancestors #更新父节点
return node_value_result[::-1] #逆序输出,得到从叶节点开始的层次遍历结果
108、将有序数组转换为二叉搜索树:将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树(一个二叉树每个节点左右两个子树的高度差的绝对值不超过1)
这道题首先是平衡二叉搜索树的概念需要了解一下,然后可以发现平衡二叉搜索树的根结点的值正好是所有节点值的中间值,即中序遍历时,根结点位于正中间(因为是平滑二叉树)(如果是偶数个结点,则位于最中间两个靠前的那个)。于是可以想到使用二分法,先把有序数组的最中间值设为根结点,然后根结点的左孩子是左半段数组的最中间值,根结点的右孩子是右半段数组的最中间值。依次这样,即可以建立一个平衡二叉搜索树。
代码依旧是递归的思想。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def sortedArrayToBST(self, nums):
"""
:type nums: List[int]
:rtype: TreeNode
"""
size=len(nums)
if size==0:
return None
if size==1:
TreeNode(nums[0])
size//=2
root=TreeNode(nums[size])
root.left=self.sortedArrayToBST(nums[:size])
root.right=self.sortedArrayToBST(nums[size+1:])
return root