返回

插入难题:求解最大值的不二法门

后端

征服 LeetCode 1881:插入后的最大值难题

在算法学习的浩瀚世界中,LeetCode 是一片算法爱好者的圣地。在这片圣地之中,一道名为 "1881. 插入后的最大值" 的难题犹如一块难以逾越的巨石,考验着算法爱好者的思维能力和代码实现技巧。今天,我们就来抽丝剥茧,层层递进,征服这道难题!

难题直击

给定一个按非递减顺序排列的整数数组 arr 和一个整数 target,要求我们在 arr 中插入 target,使得插入后的数组仍然保持非递减顺序。随后,返回插入后的最大值。

直观理解

为了解决这个问题,我们需要理解题目的两个关键要求:

  1. 插入元素:target 插入 arr 中,使得插入后的数组保持非递减顺序。
  2. 求解最大值: 插入后,返回插入后的最大值。

算法思路

要满足题目的要求,我们可以采用两种不同的算法思路:

思路 1:暴力搜索

这种方法简单直观,遍历整个 arr 数组,找到比 target 大的第一个元素,将 target 插入到该元素前面。插入后,返回插入后的最大值。

思路 2:二分查找

二分查找是一种更有效的算法,时间复杂度为 O(log n)。它利用 arr 数组有序的特性,通过二分查找法快速找到插入点。

代码实现

基于二分查找的代码实现如下:

def max_after_insertion(arr, target):
    """
    在数组中插入特定值后求解最大值

    Parameters:
        arr: 输入数组,元素按非递减顺序排列
        target: 要插入的元素

    Returns:
        插入后的最大值
    """

    # 使用二分查找找到插入点
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = left + (right - left) // 2
        if arr[mid] == target:
            return arr[mid]
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1

    # 将target插入到找到的位置
    arr.insert(left, target)

    # 返回插入后的最大值
    return max(arr)

实例分析

假设数组 arr[1, 2, 3, 4, 6, 7],要插入的元素 target5

步骤 1:二分查找插入点

  • left = 0, right = 5
  • mid = 2, arr[2] = 3 < 5, 所以 left = 3
  • left = 3, right = 5
  • mid = 4, arr[4] = 6 > 5, 所以 right = 3
  • left = 3, right = 3
  • mid = 3, arr[3] = 4 < 5, 所以 left = 4

此时,left = 4,表明插入点应在数组的第 4 个位置。

步骤 2:插入 target

target = 5 插入到数组的第 4 个位置,得到 [1, 2, 3, 4, 5, 6, 7]

步骤 3:返回最大值

插入后的最大值是 7,因此返回 7

结论

通过本文的深入解析,相信你已经掌握了征服 "1881. 插入后的最大值" 难题的方法论。无论是暴力搜索还是二分查找,只要掌握了思路,算法实现便水到渠成。愿你继续在算法学习的道路上乘风破浪,不断挑战自我,创造新的辉煌!

常见问题解答

1. 如何判断数组是否按非递减顺序排列?

可以遍历数组,比较相邻元素的大小,如果后面的元素大于或等于前面的元素,则数组按非递减顺序排列。

2. 二分查找的复杂度为什么是 O(log n)?

二分查找每次将搜索范围缩小一半,因此搜索范围的长度呈指数级下降,复杂度为 O(log n)。

3. 如果数组中存在重复元素,二分查找还会有效吗?

不会,因为二分查找的前提是数组中元素唯一。如果存在重复元素,二分查找可能无法准确找到插入点。

4. 除了二分查找,还有其他寻找插入点的算法吗?

有,可以使用线性搜索或跳跃搜索。线性搜索时间复杂度为 O(n),跳跃搜索时间复杂度为 O(√n)。

5. 如何处理数组为空的情况?

如果数组为空,直接返回 target,因为插入后的数组最大值就是 target