LeetCode刷题之路(六)

这五道题全部都是和树的遍历有关系,也是非递归的二叉树遍历写法,有前中后序三种遍历,按层遍历。总结如下。

LeetCode94二叉树的中序遍历

算法思路:二叉树的前序遍历和中序遍历代码基本一致,不同的地方在于什么时候该访问父节点。非递归的写法主要是使用一个栈来保存已经访问过的结点,其实树的前中后序三种遍历就是深度优先搜索的变形。

具体的来说,中序遍历一直将访问到的结点入栈,继续访问该结点的左子结点,直到左子结点为空,弹出栈顶结点,访问。

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        seq = []
        stack = []
        if root is None:
            return seq
        while((root is not None) | (len(stack) > 0)):
            if root is not None:
                stack.append(root)
                root = root.left
            else:
                root = stack.pop()
                seq.append(root.val)
                root = root.right
        return seq
LeetCode144二叉树的前序遍历

算法思路:前序遍历就是先访问该节点,然后再将该节点的左子节点入栈,如果该节点为空,则弹出栈顶元素,访问右子结点。

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        seq = []
        stack = []
        if root is  None:
            return seq
        while((root is not None) | (len(stack) > 0)):
            if root is not None:
                seq.append(root.val)
                stack.append(root)
                root = root.left
            else:
                root = stack.pop()
                root = root.right
        return seq
LeetCode145二叉树的后序遍历

算法思路:由于后序遍历是先访问左子结点,再访问右子节点,最后是根节点。但是如果我们按根节点,右子节点,左子节点的顺序访问,然后最后反转过来。

class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        seq = [] 
        stack = [] 
        if root is None:
            return seq
        while((root is not None)|(len(stack) > 0 )):
            if root is not None:
                seq.append(root.val)  # first visit root node
                stack.append(root)
                root = root.right # second visit rightchild node
            else:
                root = stack.pop()
                root = root.left # third visit leftchild node
        # beacause we visit by order that root,rightchild,left,
        # so we should reverse the final result
        return seq[::-1]
LeetCode102二叉树的层次遍历

算法思路:二叉树的层次遍历实际上是广度优先搜索,在树的搜索过程中,每次都要搜索完该层然后再进入下一层,广度优先搜索的的广度就体现在树的每一层上。树的层次遍历,我们需要用一个队列来保存当前结点的左右子结点,每次从队列中存储的第一个元素出队,访问该结点,判断是否有左右子结点,如果有就入队,当队列为空则结束了遍历。

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        list = []
        seq = []
        if root is None:
            return seq
        list.append(root)
        while(len(list) > 0):
            temp = []
            length_layer = len(list)
            for i in range(length_layer):
                root = list[0]
                temp.append(root.val)
                del list[0]
                if root.left is not None:
                    list.append(root.left)
                if root.right is not None:
                    list.append(root.right)
            seq.append(temp)
        return seq
LeetCode103二叉树的锯齿形层次遍历

算法思路:这道题和上面那道题非常相似,唯一需要注意的地方在于偶数层的结点应该从右到左访问,奇数层的结点应该从左到右访问。所以我们可以设置一个额外的列表来保存偶数层的结点,在代码中就是temp_list,它的左右在于将偶数层的结点反转过来,然后访问temp_list中的结点。这里值得注意的是:我们不能够在访问temp_list的结点时候,顺便将该结点的左右子结点入队,这会导致下一层的访问又是从右到左的访问顺序,我们应该按原来树的每一层结构顺序,将结点的左右子结点入队,而不是按反转过来的结点顺序,将结点的左右子结点入队。我在这里被坑了一个小时,我的天。

class Solution:
    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
        seq = []
        list = []
        if root is None:
            return seq
        list.append(root)
        layer = 0
        while(len(list) > 0):
            temp = []
            if layer % 2 == 0:
                length_layer = len(list)
                for i in range(length_layer):
                    root = list[0]
                    temp.append(root.val)
                    del list[0]
                    if root.left is not None:
                        list.append(root.left)
                    if root.right is not None:
                        list.append(root.right)
                seq.append(temp)
                layer += 1
            elif layer % 2 == 1:
                length_layer = len(list)
                temp_list = list[::-1]
                for i in range(length_layer):
                    root = temp_list[0]
                    temp.append(root.val)
                    del temp_list[0]
                    root = list[0]
                    del list[0]
                    if root.left is not None:
                        list.append(root.left)
                    if root.right is not None:
                        list.append(root.right)
                seq.append(temp)
                layer += 1
        return seq

你可能感兴趣的:(LeetCode)