小白一个,直接看评论区学习:
附上链接
题解链接:https://leetcode-cn.com/problems/symmetric-tree/solution/bfs-dui-lie-tong-shi-bao-cun-bao-cun-yao-pan-duan-/
二叉树实现链接:https://blog.csdn.net/Tonywu2018/article/details/89480282
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/symmetric-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
import collections
class TreeNode(object):
def __init__(self, data=0, left=None, right=None):
self.data = data
self.left = left
self.right = right
class BinTree(object):
def __init__(self):
self.root = None
self.ls = []
def add(self, data):
node = TreeNode(data)
if self.root is None:
self.root = node
self.ls.append(self.root)
return
treenode = self.ls[0]
if treenode.left is None:
treenode.left = node
self.ls.append(node)
elif treenode.right is None:
treenode.right = node
self.ls.append(node)
self.ls.pop(0)
def preOrederTraversal(self, root):
if root is None:
return
print(root.data)
self.preOrederTraversal(root.left)
self.preOrederTraversal(root.right)
class Solution(object):
def isSymmetric(self, Troot: BinTree) -> bool:
queue = collections.deque()
queue.append((Troot.root.left, Troot.root.right))
while queue:
left, right = queue.popleft()
if not left and not right:
continue
if not left or not right:
return False
if left.data != right.data:
return False
queue.append((left.left, right.right))
queue.append((left.right, right.left))
return True
if __name__ == '__main__':
L = [1, 2, 2, 3, 4, 4, 3]
Tree = BinTree()
for i in L:
Tree.add(i)
solution = Solution()
print(solution.isSymmetric(Tree))
这段代码中包含了二叉树的简单实现,主要是为了锻炼代码能力,不仅要会写题解,还要会写示例等。
下面就是在学习过程中自问自答:
Q:queue = collections.deque()是什么?
deque 是一个双端队列, 如果要经常从两端append 的数据, 选择这个数据结构就比较好了, 如果要实现随机访问,不建议用这个,请用列表.
deque 优势就是可以从两边append ,appendleft 数据. 这一点list 是没有的.
英语阅读时间阅读官方文档
https://docs.python.org/3.6/library/collections.html#collections.deque
Q:queue.popleft()是什么?
从左边pop
Q:queue.append((root, root))
left, right = queue.popleft()
这段代码中,不是增加的是一个元组吗,为什么popleft可以弹出两次?
这边,left,right不就是元组的简略写法吗?
Q:queue.append((left.left, right.right))
queue.append((left.right, right.left))
left, right = queue.popleft()
left和right的值又是什么?
如果传入(1, 1)
Left=1
Right=1
Queue中还剩下(1, 1)
想法:对称很简单就是说,对于有相同父节点的节点来说,
1. 左边节点的左子节点要和右边节点的右子节点值相同,
2. 左边节点的右子节点要和右边节点的左子节点值相同。
Q:Python二叉树实现基本结构和增加操作?
Python中没有结构体概念,故需要用一个类,且类中只有基本的__init__(self, data)方法来构建树节点。
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
再用另一个类来表示二叉树,且二叉树中定义列表,用来存放还能够增加子节点的节点地址。
class BinTree(object):
def __init__(self):
self.root = None # 初始化根节点为None,理解为指向一个TreeNode类的指针。
self.ls = [] # 定义列表,用于存储节点地址
def add(self, data):
# 用add方法向树结构中添加元素
node = TreeNode(data) # 实例化一个树节点
if self.root is None: # 若根节点不存在,添加根节点
self.root = node
self.ls.append(self.root) # 这里,增加了根节点地址,因为Python没有指针,对应下面的pop(0)
return
treenode = self.ls[0]
if treenode.left is None:
treenode.left = node
self.ls.append(node)
elif treenode.right is None:
treenode.right = node
self.ls.append(node)
self.ls.pop(0) # 这里,当右子节点添加完毕后,该节点无法添加节点,所以将该节点的地址删除。
# 这样,列表中剩下的就只有还能添加子节点的节点了
def preOrederTraversal(self, root):
if root is None:
return
print(root.data)
self.preOrederTraversal(root.left)
self.preOrederTraversal(root.right)