Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >2025-05-17:使数组非递减的最少除法操作次数。用go语言,给定一个整数数组 nums。 定义:对于一个正整数 x,所有严

2025-05-17:使数组非递减的最少除法操作次数。用go语言,给定一个整数数组 nums。 定义:对于一个正整数 x,所有严

作者头像
福大大架构师每日一题
发布于 2025-05-17 06:01:10
发布于 2025-05-17 06:01:10
2900
代码可运行
举报
运行总次数:0
代码可运行

2025-05-17:使数组非递减的最少除法操作次数。用go语言,给定一个整数数组 nums。

定义:对于一个正整数 x,所有严格小于 x 的正因子称为 x 的“真因数”。举例来说,2 是 4 的真因数,但对于 6 来说,6 本身则不是它的真因数。

你可以对数组中的元素进行多次操作。每次操作中,选择数组中的某个元素,将它除以该元素的最大真因数。

目标是通过若干次操作,使得最终数组元素按照非递减顺序排列。

请你计算完成此目标所需的最少操作次数,如果无法实现,请返回 -1。

1 <= nums.length <= 100000。

1 <= nums[i] <= 1000000。

输入:nums = [25,7]。

输出:1。

解释:

通过一次操作,25 除以 5 ,nums 变为 [5, 7] 。

题目来自3226。

分步骤描述过程:

  1. 1. 预处理最小质因数(LPF)数组
    • • 初始化一个大小为1,000,001的数组lpf,用于存储每个数的最小质因数(Least Prime Factor)。
    • • 遍历从2到1,000,000的每个数i
      • • 如果lpf[i]为0,说明i是质数。
      • • 对于每个质数i,遍历其所有倍数j(即j = i, 2i, 3i, ...),如果lpf[j]尚未被赋值,则将其设为i。这样lpf[j]就是j的最小质因数。
    • • 预处理完成后,lpf[x]表示x的最小质因数。例如,lpf[25] = 5lpf[7] = 7
  2. 2. 处理数组nums
    • • 从数组的倒数第二个元素开始向前遍历(即从右向左遍历):
      • • 对于当前元素nums[i],如果它比后一个元素nums[i+1]大,则需要通过操作将其减小到不超过nums[i+1]
      • • 操作的定义是将nums[i]除以其最大真因数。最大真因数可以通过nums[i] / lpf[nums[i]]得到(因为nums[i]的最小质因数lpf[nums[i]]对应其最小真因数,而最大真因数是nums[i] / lpf[nums[i]])。
      • • 执行操作:nums[i] = lpf[nums[i]](即nums[i]被替换为其最小质因数)。
      • • 操作次数ans加1。
      • • 如果操作后的nums[i]仍然大于nums[i+1],则无法使数组非递减,直接返回-1。
    • • 如果遍历完成后没有无法满足非递减的情况,返回操作次数ans
  3. 3. 示例分析
    • • 输入nums = [25, 7]
      • • 从i = 0开始(因为数组长度为2,ilen(nums)-2=0开始)。
      • nums[0] = 25nums[1] = 7大,需要进行操作。
      • lpf[25] = 5,所以nums[0]被替换为5,操作次数ans变为1。
      • • 操作后数组为[5, 7],此时5 <= 7,满足非递减。
      • • 返回操作次数1。

时间复杂度和空间复杂度:

  1. 1. 时间复杂度
    • • 预处理lpf数组:使用埃拉托斯特尼筛法的变种,时间复杂度为O(mx log log mx),其中mx = 1,000,001。这是一个近似线性的时间复杂度。
    • • 处理nums数组:遍历数组一次,每次操作的时间复杂度为O(1)(因为lpf数组是预处理的),所以总时间复杂度为O(n),其中n是数组长度。
    • • 总时间复杂度:O(mx log log mx + n)。由于mx是常数(1,000,001),可以简化为O(n)
  2. 2. 空间复杂度
    • lpf数组的大小为mx,即O(mx)
    • • 其他变量(如ans等)占用常数空间。
    • • 总空间复杂度:O(mx),即O(1,000,001),是常数空间。

总结:

  • • 预处理lpf数组是关键,它使得后续操作可以在常数时间内完成。
  • • 通过从右向左遍历数组,可以贪心地处理每个元素,确保每次操作都是必要的。
  • • 时间复杂度和空间复杂度都是线性的,但由于mx是固定的,实际表现非常高效。

Go完整代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (
    "fmt"
)

const mx = 1_000_001

var lpf = [mx]int{}

func init() {
    for i := 2; i < mx; i++ {
        if lpf[i] == 0 {
            for j := i; j < mx; j += i {
                if lpf[j] == 0 {
                    lpf[j] = i
                }
            }
        }
    }
}

func minOperations(nums []int) (ans int) {
    for i := len(nums) - 2; i >= 0; i-- {
        if nums[i] > nums[i+1] {
            nums[i] = lpf[nums[i]]
            if nums[i] > nums[i+1] {
                return-1
            }
            ans++
        }
    }
    return
}

func main() {
    nums := []int{25, 7}
    result := minOperations(nums)
    fmt.Println(result)
}

Python完整代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*-coding:utf-8-*-

mx = 1_000_001
lpf = [0] * mx

definit():
    for i inrange(2, mx):
        if lpf[i] == 0:
            for j inrange(i, mx, i):
                if lpf[j] == 0:
                    lpf[j] = i

defmin_operations(nums):
    ans = 0
    for i inrange(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

if __name__ == '__main__':
    init()
    nums = [25, 7]
    result = min_operations(nums)
    print(result)

Rust完整代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const MX: usize = 1_000_001;

fninit_lpf() ->Vec<usize> {
    letmut lpf = vec![0; MX];
    foriin2..MX {
        if lpf[i] == 0 {
            letmut j = i;
            while j < MX {
                if lpf[j] == 0 {
                    lpf[j] = i;
                }
                j += i;
            }
        }
    }
    lpf
}

fnmin_operations(nums: &mut [usize], lpf: &[usize]) ->i32 {
    letmut ans = 0;
    foriin (0..nums.len() - 1).rev() {
        if nums[i] > nums[i + 1] {
            nums[i] = lpf[nums[i]];
            if nums[i] > nums[i + 1] {
                return -1;
            }
            ans += 1;
        }
    }
    ans
}

fnmain() {
    letlpf = init_lpf();
    letmut nums = vec![25, 7];
    letresult = min_operations(&mut nums, &lpf);
    println!("{}", result);
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
2025-04-11:查询子数组最大异或值。用go语言,给定一个由 n 个整数组成的数组 nums,以及一个大小为 q 的二维数
2025-04-11:查询子数组最大异或值。用go语言,给定一个由 n 个整数组成的数组 nums,以及一个大小为 q 的二维数组 queries,其中每个查询 queries[i] = [li, ri] 要求在 nums[li..ri] 范围内找到任意子数组的最大异或值。
福大大架构师每日一题
2025/04/11
820
2025-04-11:查询子数组最大异或值。用go语言,给定一个由 n 个整数组成的数组 nums,以及一个大小为 q 的二维数
2025-06-07:零数组变换Ⅰ。用go语言,给定一个长度为 n 的整数数组 nums,以及一个二维数组 queries,每个
2025-06-07:零数组变换Ⅰ。用go语言,给定一个长度为 n 的整数数组 nums,以及一个二维数组 queries,每个查询 queries[i] 表示一个区间 [li, ri]。
福大大架构师每日一题
2025/06/07
320
2025-06-07:零数组变换Ⅰ。用go语言,给定一个长度为 n 的整数数组 nums,以及一个二维数组 queries,每个
2025-06-04:好子序列的元素之和。用go语言,给定一个整数数组 nums,一个“好子序列”是指该子序列内任意相邻的两个元
2025-06-04:好子序列的元素之和。用go语言,给定一个整数数组 nums,一个“好子序列”是指该子序列内任意相邻的两个元素之间的绝对差为1。
福大大架构师每日一题
2025/06/06
270
2025-06-04:好子序列的元素之和。用go语言,给定一个整数数组 nums,一个“好子序列”是指该子序列内任意相邻的两个元
2025-01-14:K 秒后第 N 个元素的值。用go语言,给定两个整数 n 和 k,我们开始时有一个长度为 n 的整数数组
2025-01-14:K 秒后第 N 个元素的值。用go语言,给定两个整数 n 和 k,我们开始时有一个长度为 n 的整数数组 a,其中每个元素均为 1。
福大大架构师每日一题
2025/01/15
1360
2025-01-14:K 秒后第 N 个元素的值。用go语言,给定两个整数 n 和 k,我们开始时有一个长度为 n 的整数数组
2025-01-21:使二进制数组全部等于 1 的最少操作次数Ⅰ。用go语言,给定一个二进制数组 nums,你可以进行以下操作任
2025-01-21:使二进制数组全部等于 1 的最少操作次数Ⅰ。用go语言,给定一个二进制数组 nums,你可以进行以下操作任意次数(包括0次):
福大大架构师每日一题
2025/01/22
580
2025-01-21:使二进制数组全部等于 1 的最少操作次数Ⅰ。用go语言,给定一个二进制数组 nums,你可以进行以下操作任
2025-04-18:求出数组中最大序列值。用go语言,给定一个整数数组 nums 和一个正整数 k。 定义一个长度为 2*k
2025-04-18:求出数组中最大序列值。用go语言,给定一个整数数组 nums 和一个正整数 k。 定义一个长度为 2*k 的子序列 seq 的值为:
福大大架构师每日一题
2025/04/18
480
2025-04-18:求出数组中最大序列值。用go语言,给定一个整数数组 nums 和一个正整数 k。 定义一个长度为 2*k
2025-05-23:数组的最大因子得分。用go语言,给定一个整数数组 nums。 定义“因子得分”为该数组中所有元素的最小公倍
2025-05-23:数组的最大因子得分。用go语言,给定一个整数数组 nums。
福大大架构师每日一题
2025/05/23
280
2025-05-23:数组的最大因子得分。用go语言,给定一个整数数组 nums。 定义“因子得分”为该数组中所有元素的最小公倍
2024-11-26:使数组中位数等于 K 的最少操作数。用go语言,给定一个整数数组 nums 和一个非负整数 k, 你可以通
2024-11-26:使数组中位数等于 K 的最少操作数。用go语言,给定一个整数数组 nums 和一个非负整数 k,
福大大架构师每日一题
2024/11/27
790
2024-11-26:使数组中位数等于 K 的最少操作数。用go语言,给定一个整数数组 nums 和一个非负整数 k, 你可以通
2024-09-18:用go语言,给定一个从 0 开始的长度为 n 的正整数数组 nums 和一个二维操作数组 queries,
2024-09-18:用go语言,给定一个从 0 开始的长度为 n 的正整数数组 nums 和一个二维操作数组 queries,每个操作由一个下标值 indexi 和一个数值 ki 组成。
福大大架构师每日一题
2024/09/19
1480
2024-09-18:用go语言,给定一个从 0 开始的长度为 n 的正整数数组 nums 和一个二维操作数组 queries,
2024-11-13:求出所有子序列的能量和。用go语言,给定一个整数数组nums和一个正整数k, 定义一个子序列的能量为子序列
2024-11-13:求出所有子序列的能量和。用go语言,给定一个整数数组nums和一个正整数k,
福大大架构师每日一题
2024/11/14
1160
2024-11-13:求出所有子序列的能量和。用go语言,给定一个整数数组nums和一个正整数k, 定义一个子序列的能量为子序列
2024-09-14:用go语言,给定一个正整数数组 nums,定义一个加密函数 encrypt(x),其将一个整数 x 的每一
2024-09-14:用go语言,给定一个正整数数组 nums,定义一个加密函数 encrypt(x),其将一个整数 x 的每一位数字都替换为 x 中的最大数字,然后返回加密后的数字。
福大大架构师每日一题
2024/09/18
820
2024-09-14:用go语言,给定一个正整数数组 nums,定义一个加密函数 encrypt(x),其将一个整数 x 的每一
2025-04-01:K 次乘运算后的最终数组Ⅰ。用go语言,给定一个整数数组 nums、一个整数 k 和一个乘数 multip
2025-04-01:K 次乘运算后的最终数组Ⅰ。用go语言,给定一个整数数组 nums、一个整数 k 和一个乘数 multiplier。你需要对数组 nums 执行 k 次操作。每次操作的步骤如下:
福大大架构师每日一题
2025/03/31
510
2025-04-01:K 次乘运算后的最终数组Ⅰ。用go语言,给定一个整数数组 nums、一个整数 k 和一个乘数 multip
2025-02-09:找出有效子序列的最大长度Ⅱ。用go语言,给定一个整数数组 nums 和一个正整数 k,我们定义一个子序列
2025-02-09:找出有效子序列的最大长度Ⅱ。用go语言,给定一个整数数组 nums 和一个正整数 k,我们定义一个子序列 sub 的长度为 x,如果满足以下条件,则称为有效子序列:
福大大架构师每日一题
2025/02/10
940
2025-02-09:找出有效子序列的最大长度Ⅱ。用go语言,给定一个整数数组 nums 和一个正整数 k,我们定义一个子序列
2025-01-11:求出最长好子序列Ⅰ。用go语言,给定一个整数数组 nums 和一个非负整数 k,我们需要找出满足特定条件的
2025-01-11:求出最长好子序列Ⅰ。用go语言,给定一个整数数组 nums 和一个非负整数 k,我们需要找出满足特定条件的子序列。
福大大架构师每日一题
2025/01/11
850
2025-01-11:求出最长好子序列Ⅰ。用go语言,给定一个整数数组 nums 和一个非负整数 k,我们需要找出满足特定条件的
2025-04-02:K 次乘运算后的最终数组Ⅱ。用go语言,给定一个整数数组 nums,以及两个整数 k 和 multipli
2025-04-02:K 次乘运算后的最终数组Ⅱ。用go语言,给定一个整数数组 nums,以及两个整数 k 和 multiplier。你需要对 nums 数组进行 k 次操作。每次操作的流程如下:
福大大架构师每日一题
2025/04/02
630
2025-04-02:K 次乘运算后的最终数组Ⅱ。用go语言,给定一个整数数组 nums,以及两个整数 k 和 multipli
2025-05-25:最大公约数相等的子序列数量。用go语言,给定一个整数数组 nums,需要计算满足以下条件的非空子序列对 (
2025-05-25:最大公约数相等的子序列数量。用go语言,给定一个整数数组 nums,需要计算满足以下条件的非空子序列对 (seq1, seq2) 的数量:
福大大架构师每日一题
2025/05/25
550
2025-05-25:最大公约数相等的子序列数量。用go语言,给定一个整数数组 nums,需要计算满足以下条件的非空子序列对 (
2025-01-22:使二进制数组全部等于 1 的最少操作次数Ⅱ。用go语言,给定一个二进制数组 nums,你可以对数组进行以下
2025-01-22:使二进制数组全部等于 1 的最少操作次数Ⅱ。用go语言,给定一个二进制数组 nums,你可以对数组进行以下操作任意次(包括0次):
福大大架构师每日一题
2025/01/23
790
2025-01-22:使二进制数组全部等于 1 的最少操作次数Ⅱ。用go语言,给定一个二进制数组 nums,你可以对数组进行以下
2025-04-03:统计近似相等数对Ⅱ。用go语言,你有一个正整数数组 nums。我们称两个整数 x 和 y 为“近似相等”,
2025-04-03:统计近似相等数对Ⅱ。用go语言,你有一个正整数数组 nums。我们称两个整数 x 和 y 为“近似相等”,如果我们可以对其中一个数执行至多两次操作,使得它们变得相等。这些操作包括选择 x 或 y 中的一个,交换这个数字的两个数位。
福大大架构师每日一题
2025/04/04
820
2025-04-03:统计近似相等数对Ⅱ。用go语言,你有一个正整数数组 nums。我们称两个整数 x 和 y 为“近似相等”,
2025-03-06:给定一个长度为 n 的整数组 nums,其中 n 是偶数,同时还有一个整数 k。 你可以进行一些操作,每次
2025-03-06:给定一个长度为 n 的整数组 nums,其中 n 是偶数,同时还有一个整数 k。
福大大架构师每日一题
2025/03/06
1030
2025-03-06:给定一个长度为 n 的整数组 nums,其中 n 是偶数,同时还有一个整数 k。 你可以进行一些操作,每次
2024-11-09:或值至少为 K 的最短子数组 II。用go语言,给定一个非负整数数组 nums 和一个整数 k,我们的目标
2024-11-09:或值至少为 K 的最短子数组 II。用go语言,给定一个非负整数数组 nums 和一个整数 k,我们的目标是找出数组中最短的非空子数组,使得该子数组所有元素的按位或结果至少为 k。如果找不到这样的子数组,则返回 -1。
福大大架构师每日一题
2024/11/11
1360
2024-11-09:或值至少为 K 的最短子数组 II。用go语言,给定一个非负整数数组 nums 和一个整数 k,我们的目标
推荐阅读
2025-04-11:查询子数组最大异或值。用go语言,给定一个由 n 个整数组成的数组 nums,以及一个大小为 q 的二维数
820
2025-06-07:零数组变换Ⅰ。用go语言,给定一个长度为 n 的整数数组 nums,以及一个二维数组 queries,每个
320
2025-06-04:好子序列的元素之和。用go语言,给定一个整数数组 nums,一个“好子序列”是指该子序列内任意相邻的两个元
270
2025-01-14:K 秒后第 N 个元素的值。用go语言,给定两个整数 n 和 k,我们开始时有一个长度为 n 的整数数组
1360
2025-01-21:使二进制数组全部等于 1 的最少操作次数Ⅰ。用go语言,给定一个二进制数组 nums,你可以进行以下操作任
580
2025-04-18:求出数组中最大序列值。用go语言,给定一个整数数组 nums 和一个正整数 k。 定义一个长度为 2*k
480
2025-05-23:数组的最大因子得分。用go语言,给定一个整数数组 nums。 定义“因子得分”为该数组中所有元素的最小公倍
280
2024-11-26:使数组中位数等于 K 的最少操作数。用go语言,给定一个整数数组 nums 和一个非负整数 k, 你可以通
790
2024-09-18:用go语言,给定一个从 0 开始的长度为 n 的正整数数组 nums 和一个二维操作数组 queries,
1480
2024-11-13:求出所有子序列的能量和。用go语言,给定一个整数数组nums和一个正整数k, 定义一个子序列的能量为子序列
1160
2024-09-14:用go语言,给定一个正整数数组 nums,定义一个加密函数 encrypt(x),其将一个整数 x 的每一
820
2025-04-01:K 次乘运算后的最终数组Ⅰ。用go语言,给定一个整数数组 nums、一个整数 k 和一个乘数 multip
510
2025-02-09:找出有效子序列的最大长度Ⅱ。用go语言,给定一个整数数组 nums 和一个正整数 k,我们定义一个子序列
940
2025-01-11:求出最长好子序列Ⅰ。用go语言,给定一个整数数组 nums 和一个非负整数 k,我们需要找出满足特定条件的
850
2025-04-02:K 次乘运算后的最终数组Ⅱ。用go语言,给定一个整数数组 nums,以及两个整数 k 和 multipli
630
2025-05-25:最大公约数相等的子序列数量。用go语言,给定一个整数数组 nums,需要计算满足以下条件的非空子序列对 (
550
2025-01-22:使二进制数组全部等于 1 的最少操作次数Ⅱ。用go语言,给定一个二进制数组 nums,你可以对数组进行以下
790
2025-04-03:统计近似相等数对Ⅱ。用go语言,你有一个正整数数组 nums。我们称两个整数 x 和 y 为“近似相等”,
820
2025-03-06:给定一个长度为 n 的整数组 nums,其中 n 是偶数,同时还有一个整数 k。 你可以进行一些操作,每次
1030
2024-11-09:或值至少为 K 的最短子数组 II。用go语言,给定一个非负整数数组 nums 和一个整数 k,我们的目标
1360
相关推荐
2025-04-11:查询子数组最大异或值。用go语言,给定一个由 n 个整数组成的数组 nums,以及一个大小为 q 的二维数
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验