leetcode
leetcode 2151 ~ 2200
使用质因数之和替换后可以取到的最小值

使用质因数之和替换后可以取到的最小值

难度:

标签:

题目描述

You are given a positive integer n.

Continuously replace n with the sum of its prime factors.

  • Note that if a prime factor divides n multiple times, it should be included in the sum as many times as it divides n.

Return the smallest value n will take on.

 

Example 1:

Input: n = 15
Output: 5
Explanation: Initially, n = 15.
15 = 3 * 5, so replace n with 3 + 5 = 8.
8 = 2 * 2 * 2, so replace n with 2 + 2 + 2 = 6.
6 = 2 * 3, so replace n with 2 + 3 = 5.
5 is the smallest value n will take on.

Example 2:

Input: n = 3
Output: 3
Explanation: Initially, n = 3.
3 is the smallest value n will take on.

 

Constraints:

  • 2 <= n <= 105

代码结果

运行时间: 28 ms, 内存: 16.1 MB


/*
 * Problem: Given a positive integer n, replace n with the sum of its prime factors,
 * repeating this process until n cannot be replaced anymore.
 * Return the smallest value that n can be.
 *
 * Approach:
 * 1. Create a helper function to find the prime factors of a number using streams.
 * 2. Replace n with the sum of its prime factors and repeat until n cannot be reduced further.
 * 3. Return the final value of n.
 */
import java.util.stream.IntStream;

public class Solution {
    public int smallestValue(int n) {
        while (true) {
            int sumOfPrimeFactors = sumPrimeFactors(n);
            if (sumOfPrimeFactors == n) break;
            n = sumOfPrimeFactors;
        }
        return n;
    }

    private int sumPrimeFactors(int n) {
        int sum = 0;
        for (int i = 2; i * i <= n; i++) {
            while (n % i == 0) {
                sum += i;
                n /= i;
            }
        }
        if (n > 1) sum += n;
        return sum;
    }

    public static void main(String[] args) {
        Solution sol = new Solution();
        System.out.println(sol.smallestValue(15)); // Output: 5
        System.out.println(sol.smallestValue(3));  // Output: 3
    }
}

解释

方法:

这个题解的思路是通过不断重复替换整数n为其质因数之和,直到n不能再变小。在每次迭代中,算法首先尝试从最小的质因数2开始,逐步检查每个数是否是n的质因数,并将其累加到变量j中。如果在检查到i * i > n时仍有剩余的n大于1,这意味着n本身是一个质因数,此时将其加到j中。如果新的j与原始的n相同,则说明n已经是其质因数之和的最小值,算法结束返回j。

时间复杂度:

O(n * sqrt(n))

空间复杂度:

O(1)

代码细节讲解

🦆
在算法中,如何保证每次迭代的n值都是正确的质因数之和,而不是错误地包含非质因数的组合?
算法通过质因数分解确保每次迭代的n值都仅包含n的质因数。在循环中,算法从2开始递增,检查每个数是否能整除n。如果能,则该数是n的质因数,并且会不断除以该因数直至不能整除为止。这样,算法确保加入到j中的每个因数都是n的质因数,不存在非质因数的组合。
🦆
算法在确定n无法进一步减小时即停止迭代,这一逻辑是否总是有效?是否有可能出现在某些特定输入下此逻辑导致提前终止?
这一逻辑通常是有效的,因为每次迭代的目的是通过质因数之和减小n的值。如果在某次迭代后n的值没有变化,表明n已经是其所有质因数的和,且无法通过当前的方法进一步简化。因此,算法停止是合理的。在此算法框架下,不会出现因特定输入导致的提前终止。
🦆
为什么选择从2开始检查每个数是否为n的质因数,而不是从一个更高的数开始?这种选择对算法效率有何影响?
从2开始检查是因为2是最小的质因数,并且任何合数都至少有一个不大于其平方根的质因数。从2开始可以确保按照从小到大的顺序识别并分解出所有质因数。如果从更高的数开始,可能会错过较小的质因数,导致算法无法正确分解n。从2开始虽然可能会略增加迭代次数,但这保证了算法的正确性和全面性。
🦆
在检查到i * i > n时,算法假设剩余的n大于1是一个质因数并将其加到j中。这种假设在什么情况下可能不成立?
该假设总是成立的。当i * i > n时,如果n大于1,则n不能被任何小于或等于其平方根的数整除。因此,n必须是质数,因为质数的定义是只能被1和自身整除。所以这种情况下,将n加入到j是正确的。

相关问题