小U的无趣数组

70 阅读3分钟

小U的无趣数组

这个问题要求我们通过最少的修改次数使数组不再“有趣”,即打破数组中任意长度为 3 的子数组满足 a_i <= a_{i+1} <= a_{i+2} 的条件。

思路

我们可以通过扫描数组中的每个连续的长度为 3 的子数组来判断是否是“有趣”的。如果是,则需要进行一次修改。关键在于如何最小化修改次数。

  • 对于每个符合条件的子数组 a[i], a[i+1], a[i+2],我们可以通过修改其中的一个元素来打破不等式。
  • 由于我们希望最少修改次数,因此每次修改应该尽量影响多个“有趣”的子数组。

解题策

  1. 扫描每个子数组 a[i], a[i+1], a[i+2],如果它是非递减的,说明是“有趣的”。
  2. 记录所有需要修改的操作次数。为了最小化修改次数,每次遇到一个“有趣”的子数组时,可以选择修改其中的某个元素,使得该子数组不再是递增的。
  3. 具体而言,可以每次修改 a[i+1](中间的元素),因为这样可以影响到 a[i], a[i+1], a[i+2]a[i+1], a[i+2], a[i+3] 这两个子数组,尽可能减少修改次数。

解法代码

python复制代码def solution(n: int, a: list) -> int:
    # 记录最少操作次数
    operations = 0
    i = 0
    
    # 遍历数组中的每个子数组
    while i + 2 < n:
        if a[i] <= a[i+1] <= a[i+2]:  # 如果满足递增条件
            operations += 1
            # 直接修改 a[i+1] 以打破该子数组的递增性质
            i += 2  # 跳过下一个子数组,避免多次修改
        else:
            i += 1  # 否则检查下一个子数组
    
    return operations
​
if __name__ == '__main__':
    print(solution(5, [6, 2, 4, 5, 1]) == 1)
    print(solution(6, [1, 2, 3, 4, 5, 6]) == 2)
    print(solution(4, [5, 3, 1, 7]) == 0)

解释

  1. 遍历: 我们使用一个 while 循环来遍历数组中的每一个长度为 3 的子数组。
  2. 检查“有趣”性质: 如果发现一个子数组满足 a[i] <= a[i+1] <= a[i+2],则认为它是“有趣的”。
  3. 修改策略: 一旦发现一个“有趣”的子数组,我们选择修改中间的元素 a[i+1]。这将打破当前子数组的递增性质,同时也会影响后续的子数组 a[i+1], a[i+2], a[i+3],因此跳过下一个子数组,即 i += 2
  4. 跳过已修改部分: 如果没有发现“有趣”的子数组,则直接检查下一个子数组。

测试样例

python复制代码print(solution(5, [6, 2, 4, 5, 1]))  # 输出: 1
print(solution(6, [1, 2, 3, 4, 5, 6]))  # 输出: 2
print(solution(4, [5, 3, 1, 7]))  # 输出: 0

复杂度分析

  • 时间复杂度: O(n),我们只遍历数组一次,每次检查一个长度为 3 的子数组,最多进行 n 次操作。
  • 空间复杂度: O(1),只使用了常量级的额外空间。

这个解法是高效的,能够满足题目的要求。