LeetCode 题解工作台
使数组非递减的最少除法操作次数
给你一个整数数组 nums 。 一个正整数 x 的任何一个 严格小于 x 的 正 因子都被称为 x 的 真因数 。比方说 2 是 4 的 真因数 ,但 6 不是 6 的 真因数 。 你可以对 nums 的任何数字做任意次 操作 ,一次 操作 中,你可以选择 nums 中的任意一个元素,将它除以它的 …
4
题型
5
代码语言
3
相关题
当前训练重点
中等 · 贪心·invariant
答案摘要
根据题目描述, 如果整数 是质数,那么它的最大真因数是 ,那么 $x / 1 = x$,即 不能再被除了;
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 贪心·invariant 题型思路
题目描述
给你一个整数数组 nums 。
一个正整数 x 的任何一个 严格小于 x 的 正 因子都被称为 x 的 真因数 。比方说 2 是 4 的 真因数,但 6 不是 6 的 真因数。
你可以对 nums 的任何数字做任意次 操作 ,一次 操作 中,你可以选择 nums 中的任意一个元素,将它除以它的 最大真因数 。
你的目标是将数组变为 非递减 的,请你返回达成这一目标需要的 最少操作 次数。
如果 无法 将数组变成非递减的,请你返回 -1 。
示例 1:
输入:nums = [25,7]
输出:1
解释:
通过一次操作,25 除以 5 ,nums 变为 [5, 7] 。
示例 2:
输入:nums = [7,7,6]
输出:-1
示例 3:
输入:nums = [1,1,1,1]
输出:0
提示:
1 <= nums.length <= 1051 <= nums[i] <= 106
解题思路
方法一:预处理 + 贪心
根据题目描述,
如果整数 是质数,那么它的最大真因数是 ,那么 ,即 不能再被除了;
如果整数 不是质数,我们假设 的最大真因数为 ,那么 一定是质数,因此,我们寻找最小质数 ,使得 ,使得 变成 ,此时无法再被除了。
因此,我们可以预处理出 到 的每个整数的最小质因数,然后从右往左遍历数组,如果当前元素大于下一个元素,我们将当前元素变为它的最小质因数,如果当前元素变为它的最小质因数后,仍然大于下一个元素,说明无法将数组变成非递减的,返回 。否则,操作次数加一。继续遍历,直到遍历完整个数组。
预处理的时间复杂度为 ,其中 ,遍历数组的时间复杂度为 ,其中 为数组的长度。空间复杂度为 。
mx = 10**6 + 1
lpf = [0] * (mx + 1)
for i in range(2, mx + 1):
if lpf[i] == 0:
for j in range(i, mx + 1, i):
if lpf[j] == 0:
lpf[j] = i
class Solution:
def minOperations(self, nums: List[int]) -> int:
ans = 0
for i in range(len(nums) - 2, -1, -1):
if nums[i] > nums[i + 1]:
nums[i] = lpf[nums[i]]
if nums[i] > nums[i + 1]:
return -1
ans += 1
return ans
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | complexity depends on the number of division operations applied to each element, potentially O(n log m) where n is array length and m is the maximum element. Space complexity is O(1) extra beyond the input array. |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Are you considering the largest proper divisor in each step?
- question_mark
Can you explain why iterating backward simplifies maintaining the invariant?
- question_mark
How do you handle elements that cannot be reduced further but still violate the non-decreasing property?
常见陷阱
外企场景- error
Dividing elements unnecessarily instead of only when they violate the non-decreasing condition.
- error
Iterating forward instead of backward, which complicates invariant validation.
- error
Forgetting to return -1 when an element cannot be reduced enough to satisfy the sequence.
进阶变体
外企场景- arrow_right_alt
Compute minimum multiplication operations to make an array non-increasing.
- arrow_right_alt
Allow division by any proper divisor rather than only the greatest and track minimum operations.
- arrow_right_alt
Apply similar greedy operations on 2D arrays row by row while maintaining non-decreasing order.