[剑指Offer]26~29

[剑指Offer]26~29

学习使用工具

剑指Offer http://itmyhome.com/sword-means-offer/sword-means-offer.pdf

LeetCode的剑指Offer题库 https://leetcode.cn/problemset/all/

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

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

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

例如:

给定的树 A:

    3

   / \

  4   5

 / \

1   2

给定的树 B:

    4 

  /

1

返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

示例 1:

输入:A = [1,2,3], B = [3,1]
输出:false

示例 2:

输入:A = [3,4,5,1,2], B = [4,1]
输出:true

限制:

0 <= 节点个数 <= 10000

解法:

写两个递归。一个dfs,用于判断子树是否匹配;一个递归遍历A,当遍历到和B根节点val相等的节点时,调用dfs进行递归判定。整体不难,但是两层思路刚拿到题的时候不是很好捋清。

def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
        if not (A and B):
            return False

        def dfs(A: TreeNode, B: TreeNode):
            if not B:
                return True
            if not A:
                return False
                
            if not A.val == B.val:
                return False
            else:
                return dfs(A.left, B.left) and dfs(A.right, B.right)

        def travel(A: TreeNode, B: TreeNode):
            if not A:
                return False
            if A.val == B.val:
                if dfs(A, B):
                    return True
            return travel(A.left, B) or travel(A.right, B)

        return travel(A, B)

剑指 Offer 27. 二叉树的镜像

请完成一个函数,输入一个二叉树,该函数输出它的镜像。

例如输入:

     4

   /   \

  2     7

 / \   / \

1   3 6   9

镜像输出:

     4

   /   \

  7     2

 / \   / \

9   6 3   1

示例:

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

限制:

0 <= 节点个数 <= 1000

解法:

递归。先递归,再交换。

def mirrorTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return None

        temp = self.mirrorTree(root.left)
        root.left = self.mirrorTree(root.right)
        root.right = temp

        return root

剑指 Offer 28. 对称的二叉树

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

例如,二叉树 [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

限制:

0 <= 节点个数 <= 1000

解法:

递归。在递归中,当p和q都为空时,返回真;当p和q其中有一个为空,或者val值不相等时,返回假;当p和q的val值相等时,分别判断p的左子树与q的右子树是否相等、p的右子树与q的左子树是否相等。

def isSymmetric(self, root: TreeNode) -> bool:
        def check(p: TreeNode, q: TreeNode):
            if not (p or q):
                return True
            if not (p and q):
                return False
            
            if not p.val == q.val:
                return False
            
            return check(p.left, q.right) and check(p.right, q.left)

        return check(root, root)

剑指 Offer 29. 顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

限制:

  • 0 <= matrix.length <= 100
  • 0 <= matrix[i].length <= 100

解法:

虽然这题标着Easy但我感觉不是很简单啊!一翻在主站是算中等的,为啥啊!想了很久也改了半天。

思路:

  • 每一圈的遍历方向变化是固定的(先向右,再向下,再向左,再向上)
  • 设定四个方向的边界,每次改变方向时,刚刚被遍历的边界收束(向中心移动)
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        if not matrix or not matrix[0]: # 判空
            return []
		
        # 初始化边界条件
        u = 0
        d = len(matrix)
        l = 0
        r = len(matrix[0])

        num = 0 # 计数
        max = len(matrix) * len(matrix[0]) # 元素总数
        ans = [0] * max # 初始化结果数组

        while num < max :# 当计数值已经到达元素总数时,break
            for i in range(l, r):# 沿着上边界,从左向右将元素加入结果数组
                ans[num] = matrix[u][i]
                num += 1
            u += 1 # 上边界下移
            if num == max :
                break
            for i in range(u, d):# 沿着右边界,从上向下将元素加入结果数组
                ans[num] = matrix[i][r - 1]
                num += 1
            r -= 1 # 右边界左移
            if num == max :
                break
            for i in range(r - 1, l - 1, -1):# 沿着下边界,从右向左将元素加入结果数组
                ans[num] = matrix[d - 1][i]
                num += 1
            d -= 1 # 下边界上移
            if num == max :
                break
            for i in range(d - 1, u - 1, -1):# 沿着左边界,从下向上将元素加入结果数组
                ans[num] = matrix[i][l]
                num += 1
            l += 1
            if num == max :
                break

        return ans
posted @ 2023-03-06 14:23  无机呱子  阅读(5)  评论(0编辑  收藏  举报