【树-02】树的题目解析

目录

  1. 剑指 Offer 54. 二叉搜索树的第k大节点
  2. 剑指 Offer 28. 对称的二叉树/101. 对称二叉树
  3. 剑指 Offer 32 - II. 从上到下打印二叉树 II/102. 二叉树的层序遍历
  4. 剑指 Offer 32 - III. 从上到下打印二叉树 III
  5. 剑指 Offer 32 - I. 从上到下打印二叉树

一、剑指 Offer 54. 二叉搜索树的第k大节点

1.1 问题

给定一棵二叉搜索树,请找出其中第k大的节点。

示例 1:

输入: root = [3,1,4,null,2], k = 1

3

/ \

1 4

\

2

输出: 4

示例 2:

输入: root = [5,3,6,2,4,null,null,1], k = 3

5

/ \

3 6

/ \

2 4

/

1

输出: 4

1.2 代码(使用递归)

# Definition for a binary tree node.

# class TreeNode:

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution:

    def kthLargest(self, root: TreeNode, k: int) -> int:

        def dfs(root):    #右根左的形式递归调用

            if not root :

                return

            dfs(root.right)

            if self.k == 0:

                return 

            self.k -= 1

            if self.k == 0:

                self.res = root.val

            dfs(root.left)

        self.k = k   #这个不能少,可以带入到dfs函数中,不能在下面带入函数中

        dfs(root)

        return self.res

1.3 代码(不用递归)

# Definition for a binary tree node.

# class TreeNode:

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution:

    def kthLargest(self, root: TreeNode, k: int) -> int:

        stack  = []     #右根左的形式入栈数据

        p = root        #用于指向当前节点

        count = 0       #用于计算当前节点第几大

        while p or stack:

            while p:

                stack.append(p)

                p = p.right

            if stack:

                curr = stack.pop()

                count += 1

                if count == k:return curr.val

                p = curr.left

二、剑指 Offer 28. 对称的二叉树/101. 对称二叉树

2.1 问题

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。例如,二叉树 [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

示例 1

输入:root = [1,2,2,3,4,4,3]

输出:true

示例 2

输入:root = [1,2,2,null,3,null,3]

输出:false

2.2 代码一(递归实现)

# 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: TreeNode) -> bool:

        def dfs(t1, t2):

            递归的终止条件是两个节点都为空

            或者两个节点中有一个为空

            或者两个节点的值不相等

            if not(t1 or t2):

                return True

            if not(t1 and t2 ):

                return False

            return (t1.val == t2.val) and dfs(t1.right,t2.left) and dfs(t1.left , t2.right)

        return dfs(root,root)

   

2.3 代码二(队列实现)

class Solution:

    def isSymmetric(self, root: TreeNode) -> bool:

        if not root or not(root.left or root.right):

            return True

        queue = [root.left,root.right]

        while queue:

            left = queue.pop()

            right = queue.pop()

            if not(left or right):#两个都为空,继续循环

                continue

            if not(left and right): #两个有一个不空,这False

                return False

            if left.val != right.val:

                return False

            将左节点的左孩子, 右节点的右孩子放入队列

            queue.append(left.left)

            queue.append(right.right)

            将左节点的右孩子,右节点的左孩子放入队列

            queue.append(left.right)

            queue.append(right.left)

        return True

   

三、剑指 Offer 32 - II. 从上到下打印二叉树 II/102. 二叉树的层序遍历

3.1 题目

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

例如:

给定二叉树: [3,9,20,null,null,15,7],

3

/ \

9 20

/ \

15 7

返回其层次遍历结果:

[

[3],

[9,20],

[15,7]

]

   

3.2 代码(BFS,按层次遍历)

class Solution:

    def levelOrder(self, root: TreeNode) -> List[List[int]]:

        if not root :

            return []

        res = []

        queue = collections.deque()

        queue.append(root)

        while queue:

            temp = []

            for _ in range(len(queue)): #思路很好,虽然后面有加入,但是不影响目前层的遍历

                node = queue.popleft()  #要求从底部出去

                temp.append(node.val)

                if node.left:

                    queue.append(node.left)

                if node.right:

                    queue.append(node.right)

            res.append(temp)

        return res

四、剑指 Offer 32 - III. 从上到下打印二叉树 III

4.1 题目

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

例如:

给定二叉树: [3,9,20,null,null,15,7],

3

/ \

9 20

/ \

15 7

返回其层次遍历结果:

[

[3],

[20,9],

[15,7]

]

4.2 代码(BFS,按层次遍历+双端队列,和上一题差不多)

class Solution:

    def levelOrder(self, root: TreeNode) -> List[List[int]]:

        if not root :

            return []

        res =[]

        queue = collections.deque()

        queue.append(root)

        while queue:

            temp = collections.deque()

            for _ in range(len(queue)):

                node = queue.popleft()

                if len(res)%2:   偶数层 -> 队列头部

                    temp.appendleft(node.val)

                else:temp.append(node.val)   奇数层 -> 队列尾部

                if   node.left :

                    queue.append(node.left)

                if   node.right:

                    queue.append(node.right)

            res.append(list(temp))   #注意,这里需要用list

        return res

五、剑指 Offer 32 - I. 从上到下打印二叉树

5.1 问题

从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

例如:

给定二叉树: [3,9,20,null,null,15,7],

3

/ \

9 20

/ \

15 7

返回:

[3,9,20,15,7]

5.2 代码(感觉这一题比上面两题要简单,但是标注为中)

class Solution:

    def levelOrder(self, root: TreeNode) -> List[int]:

        if not root : return []

        res =[]

        queue = collections.deque()

        queue.append(root)

        while queue:

            for _ in range(len(queue)):

                node = queue.popleft()

                res.append(node.val)

                if node.left :queue.append(node.left)

                if node.right:queue.append(node.right)

        return res

参考文献

1https://leetcode-cn.com/

   

posted @ 2020-08-15 22:48  忆凡人生  阅读(215)  评论(0编辑  收藏  举报