【剑指offer刷题记录】查找算法+搜索与回溯11-50-32-26-27

本文介绍了几种基于二叉树的问题解决方案,包括使用二分法查找旋转数组最小数字,利用哈希表找字符串中首次出现的唯一字符,以及二叉树的层次遍历。对于层次遍历,分别展示了从上到下按层打印、按层反向打印和之字形打印的方法。此外,还讨论了判断子结构和构造二叉树镜像的算法,涉及递归和栈的应用。
摘要由CSDN通过智能技术生成

剑指11:旋转数组的最小数字(简单)
问题描述:
在这里插入图片描述
在这里插入图片描述
思路:二分法,得到右排序数组的第一位
在这里插入图片描述

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        i,j = 0, len(numbers)-1
        while(i<j):
            m = (i+j)//2
            if numbers[m]>numbers[j]:
                i = m + 1
            elif numbers[m]<numbers[j]:
                j = m
            else:
                j-=1
        return numbers[i]

剑指50:第一个只出现一次的字符(简单)
问题描述:在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
在这里插入图片描述
思路:哈希表/有序哈希表
在这里插入图片描述

哈希表:
class Solution:
    def firstUniqChar(self, s: str) -> str:
        dic = {}
        for c in s:
            dic[c] = not c in dic
        for c in s:
            if dic[c]:return c
        return " "

有序哈希表:
class Solution:
    def firstUniqChar(self, s: str) -> str:
        dic = collections.OrderedDict()
        for c in s:
            dic[c] = not c in dic
        for k, v in dic.items():
            if v: return k
        return ' '

剑指32(1)(2)(3):从上到下打印二叉树(简单)
问题描述:从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
在这里插入图片描述
思路:

  • 题目要求的二叉树的从上至下打印(即按层打印),又称为二叉树的广度优先搜索(BFS)。
  • BFS 通常借助队列的先入先出特性来实现。
class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        if not root:return []
        res,quene = [], collections.deque()
        quene.append(root)
        while(quene):
            node = quene.popleft()
            res.append(node.val)
            if node.left:quene.append(node.left)
            if node.right:quene.append(node.right)
        return res

问题描述:
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
在这里插入图片描述
思路:和上一题相同,广度优先搜索,注意for循环的使用。

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:return []
        res, quene = [],[]
        quene.append(root)
        while(quene):
            tmp = []
            i = 1
            for i in range(len(quene)):
                node = quene.pop(0)
                tmp.append(node.val)
                if node.left:quene.append(node.left)
                if node.right:quene.append(node.right)
                i+=1
            res.append(tmp)
        return res

问题描述:请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
在这里插入图片描述
思路:奇偶层的判断

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:return []
        res,quene = [],[]
        quene.append(root)
        cont = 1
        while(quene):
            tmp = []
            i = 1
            for i in range(len(quene)):
                node = quene.pop(0)
                tmp.append(node.val)
                if node.left:quene.append(node.left)
                if node.right:quene.append(node.right)
                i+=1
            if cont%2:res.append(tmp)
            else:res.append(tmp[::-1])
            cont+=1
        return res

剑指26:树的子结构(中等)
问题描述:输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)B是A的子结构, 即 A中有出现和B相同的结构和节点值。
在这里插入图片描述
思路:递归(怎么想出来这样写的 好厉害阿T_T

class Solution:
    def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
        def recur(A,B):   
            if not B:return True
            if not A or A.val != B.val:return False
            return recur(A.left,B.left) and recur(A.right,B.right)
        return bool(A and B) and (recur(A,B) or (self.isSubStructure(A.left,B)) or self.isSubStructure(A.right,B))

剑指27:二叉树的镜像(简单)
问题描述:请完成一个函数,输入一个二叉树,该函数输出它的镜像。
在这里插入图片描述
思路:辅助栈,同时要注意return的是一个TreeNode类型,不是前面几题的list类型。

class Solution:
    def mirrorTree(self, root: TreeNode) -> TreeNode:
        if not root:return
        stack = []
        stack.append(root)
        while(stack):
            node = stack.pop(0)
            if node.left:stack.append(node.left)
            if node.right:stack.append(node.right)
            node.left, node.right = node.right, node.left
        return root
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值