[剑指Offer]53~55

[剑指Offer]53~55

学习使用工具

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

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

剑指 Offer 53 - I. 在排序数组中查找数字 I

统计一个数字在排序数组中出现的次数。

示例 1:

输入: nums = [5,7,7,8,8,10], target = 8
输出: 2

示例 2:

输入: nums = [5,7,7,8,8,10], target = 6
输出: 0

提示:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109
  • nums 是一个非递减数组
  • -109 <= target <= 109

解法:

虽然很简单,解法也很多,但面试里出现这题大概率是希望用二分来解题。考虑中间值的情况,如果中间值比目标值小则缩短左边界,比目标值大则缩短右边界。如果和目标值相同,则扩散寻找目标值边界。

def search(self, nums: List[int], target: int) -> int:
        if not nums:
            return 0

        l = 0
        r = len(nums) - 1
        m = (l + r) // 2

        while l < r:
            if nums[m] < target:
                l = m + 1
            elif nums[m] > target:
                r = m - 1
            else:
                l = m
                r = m
                while l > 0 and nums[l - 1] == target:
                    l -= 1
                while r < len(nums) - 1 and nums[r + 1] == target:
                    r += 1
                break
            m = (l + r) // 2

        if nums[l] == target:
            return r - l + 1
        else:
            return 0

剑指 Offer 53 - II. 0~n-1中缺失的数字

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

示例 1:

输入: [0,1,3]
输出: 2

示例 2:

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

限制:

1 <= 数组长度 <= 10000

解法:

只要是有序数组就考虑二分解题。按照题目情况,未缺失的数组中每个数组元素值应当与其下标值相同;出现缺失后,数组元素开始与下标不同。因此,当中间值与下标值相同时,说明缺失发生在右半边,左边界缩短;当中间值与下标值不同时,说明缺失发生在左半边,右边界缩短。最后左边界将定位到缺失发生的位置,输出即可。

def missingNumber(self, nums: List[int]) -> int:
        l = 0
        r = len(nums) - 1

        while l <= r:
            m = (l + r) // 2
            if nums[m] == m:
                l = m + 1
            else:
                r = m - 1

        return l

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

给定一棵二叉搜索树,请找出其中第 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 ≤ k ≤ 二叉搜索树元素个数

解法:

二叉搜索树的中序遍历结果构成一个升序序列,返回中序序列的倒数第k个值即可。

class Solution:
    def __init__(self):
        self.ans = []
    def kthLargest(self, root: TreeNode, k: int) -> int:
        def midtravel(root: TreeNode):
            if not root:
                return
            midtravel(root.left)
            self.ans.append(root)
            midtravel(root.right)

        midtravel(root)

        return self.ans[-k].val

剑指 Offer 55 - I. 二叉树的深度

输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。

例如:

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

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3 。

提示:

节点总数 <= 10000

解法:

深度优先搜索,每次返回当前最大深度即可。

def maxDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        deep = 1
        deep += max(self.maxDepth(root.left), self.maxDepth(root.right))
        return deep
posted @ 2023-03-06 14:45  无机呱子  阅读(17)  评论(0编辑  收藏  举报