小U的无趣数组
这个问题要求我们通过最少的修改次数使数组不再“有趣”,即打破数组中任意长度为 3 的子数组满足 a_i <= a_{i+1} <= a_{i+2} 的条件。
思路
我们可以通过扫描数组中的每个连续的长度为 3 的子数组来判断是否是“有趣”的。如果是,则需要进行一次修改。关键在于如何最小化修改次数。
- 对于每个符合条件的子数组
a[i], a[i+1], a[i+2],我们可以通过修改其中的一个元素来打破不等式。 - 由于我们希望最少修改次数,因此每次修改应该尽量影响多个“有趣”的子数组。
解题策
- 扫描每个子数组
a[i], a[i+1], a[i+2],如果它是非递减的,说明是“有趣的”。 - 记录所有需要修改的操作次数。为了最小化修改次数,每次遇到一个“有趣”的子数组时,可以选择修改其中的某个元素,使得该子数组不再是递增的。
- 具体而言,可以每次修改
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)
解释
- 遍历: 我们使用一个
while循环来遍历数组中的每一个长度为 3 的子数组。 - 检查“有趣”性质: 如果发现一个子数组满足
a[i] <= a[i+1] <= a[i+2],则认为它是“有趣的”。 - 修改策略: 一旦发现一个“有趣”的子数组,我们选择修改中间的元素
a[i+1]。这将打破当前子数组的递增性质,同时也会影响后续的子数组a[i+1], a[i+2], a[i+3],因此跳过下一个子数组,即i += 2。 - 跳过已修改部分: 如果没有发现“有趣”的子数组,则直接检查下一个子数组。
测试样例
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),只使用了常量级的额外空间。
这个解法是高效的,能够满足题目的要求。