Smallest Value After Replacing With Sum of Prime Factors
MedPrompt
You are given a positive integer n.
Continuously replace n with the sum of its prime factors.
- Note that if a prime factor divides
nmultiple times, it should be included in the sum as many times as it dividesn.
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
Approaches
3 approaches with complexity analysis and trade-offs.
This approach directly simulates the process by repeatedly calculating the sum of prime factors and updating the number. For the factorization step, it uses a basic and inefficient trial division method where potential factors are checked up to the number itself.
Algorithm
- The main function
smallestValue(n)operates in a loop. - In each iteration, it computes the sum of prime factors of the current
nby calling a helper function,getSumOfPrimeFactors(n). - The helper function finds prime factors by trial division, iterating a potential divisor
dfrom 2 upwards. For a given numberk, this check can go up tokitself. - The loop continues to divide the number by
das long as it is divisible, addingdto a running sum. - If the divisor
dis not a factor, it is incremented. - The main loop checks if the calculated sum is equal to the current
n. If they are equal, a fixed point is reached, andnis returned. - Otherwise,
nis updated to the new sum, and the loop continues.
Walkthrough
The core of this method is a loop that continues until the number n stabilizes. A number stabilizes when it is equal to the sum of its own prime factors (e.g., a prime number or 4). The value of n is guaranteed to converge because the sum of prime factors of a composite number (other than 4) is strictly less than the number itself, leading to a decreasing sequence.
The factorization is performed naively. For a number k, we start checking for divisibility from d = 2. If k is divisible by d, we add d to our sum and divide k by d, repeating this until it's no longer divisible. Then we move to the next potential divisor d+1. This process continues until the number is reduced to 1.
class Solution { public int smallestValue(int n) { while (true) { int sumOfPrimeFactors = getSumOfPrimeFactors(n); if (sumOfPrimeFactors == n) { break; } n = sumOfPrimeFactors; } return n; } private int getSumOfPrimeFactors(int k) { if (k <= 3) { // Base cases for small primes return k; } int sum = 0; int temp_k = k; int d = 2; while (temp_k > 1) { if (temp_k % d == 0) { sum += d; temp_k /= d; } else { d++; } } return sum; }}Complexity
Time
O(K * N), where K is the number of iterations until convergence and N is the value of the number. In the worst case, factorizing a large prime N takes O(N) time. Since K is small, the complexity is dominated by the factorization of the initial input `n`.
Space
O(1) extra space.
Trade-offs
Pros
Conceptually simple and easy to implement.
Cons
Highly inefficient, especially for large prime numbers or numbers with large prime factors.
The time complexity for factorizing a single number
kcan be up toO(k), which is very slow for the given constraints.
This approach uses the Sieve of Eratosthenes to precompute the smallest prime factor for every number up to the given constraint. This precomputation allows for very fast factorization of any number in the range. While each factorization is quick, the initial setup time and space usage are considerable.
Algorithm
- A one-time precomputation step is performed to build a Smallest Prime Factor (SPF) array for all numbers up to a maximum limit (e.g., 100001).
- This is done using a Sieve of Eratosthenes variant, which populates
spf[i]with the smallest prime that dividesi. - The main
smallestValue(n)function then enters a loop that continues untilnstabilizes. - In each iteration, it calls a helper function
getSumOfPrimeFactors(n)that uses the precomputedspfarray. - This helper function calculates the sum by repeatedly dividing
nby its smallest prime factor (spf[n]) and adding that factor to a sum, untilnbecomes 1. - The main loop terminates when the sum equals
n, returning the final value.
Walkthrough
The main idea is to trade space and a one-time precomputation cost for faster subsequent calculations. We first create an array, spf, of size 100001. We initialize spf[i] = i. Then, we iterate from 2 upwards. When we find a prime number p (where spf[p] == p), we iterate through its multiples j and set spf[j] = p if j's smallest prime factor hasn't been found yet. This fills the spf array in O(MAX_N * log(log(MAX_N))) time.
Once the spf array is ready, calculating the sum of prime factors for a number k is efficient. We just repeatedly add spf[k] to our sum and update k to k / spf[k] until k becomes 1. This factorization takes only O(log k) time. The overall simulation loop remains the same.
class Solution { private static final int MAX_N = 100001; private static final int[] spf = new int[MAX_N]; static { for (int i = 0; i < MAX_N; i++) { spf[i] = i; } for (int i = 2; i * i < MAX_N; i++) { if (spf[i] == i) { // i is a prime number for (int j = i * i; j < MAX_N; j += i) { if (spf[j] == j) { // if spf[j] is not set yet spf[j] = i; } } } } } public int smallestValue(int n) { while (true) { int sumOfPrimeFactors = getSumOfPrimeFactors(n); if (sumOfPrimeFactors == n) { break; } n = sumOfPrimeFactors; } return n; } private int getSumOfPrimeFactors(int k) { if (k < 4) return k; int sum = 0; int temp_k = k; while (temp_k > 1) { sum += spf[temp_k]; temp_k /= spf[temp_k]; } return sum; }}Complexity
Time
O(MAX_N * log(log(MAX_N)) + K * log(N)). The precomputation time dominates for a single call, making it less efficient than the optimized trial division approach in this specific problem context.
Space
O(MAX_N), where MAX_N is the upper limit for the sieve (100001 in this case).
Trade-offs
Pros
Extremely fast factorization (
O(log n)) after the initial setup.Very efficient if the
smallestValuefunction were to be called multiple times with different inputs.
Cons
Requires a large amount of extra space for the SPF array,
O(MAX_N).Incurs a significant upfront time cost for the sieve precomputation, which makes it slower than the optimized trial division for a single function call.
This approach refines the factorization step by using an optimized trial division method. Instead of checking for divisors all the way up to n, it only checks up to sqrt(n). This is based on the property that any composite number n must have a prime factor less than or equal to sqrt(n). This optimization makes the process significantly faster without requiring extra space.
Algorithm
- The main
smallestValue(n)function works in a loop, same as the other approaches. - The key improvement is in the
getSumOfPrimeFactors(n)helper function. - To factorize a number
k, it iterates through potential divisorsdonly up tosqrt(k). - It first handles all factors of 2 separately.
- Then, it iterates through odd numbers
dfrom 3 up tosqrt(k). - For each
d, it repeatedly divideskand addsdto the sum. - After the loop, if the remaining value of
kis greater than 1, this remaining value must be a prime factor itself, so it's added to the sum. - The main loop continues this process until
nconverges to a fixed point.
Walkthrough
The overall iterative structure to find the smallest value remains unchanged. The efficiency gain comes from the prime factorization logic. For any number k, we can find its prime factors by checking for divisibility only up to sqrt(k).
The algorithm proceeds as follows:
- In a loop, calculate the sum of prime factors for the current
n. - To get the sum, we iterate
ifrom 2 up tosqrt(n). - For each
i, we check if it dividesn. If it does, we addito a running sum and dividenbyirepeatedly until it's no longer divisible. - After the loop finishes, if
nhas been reduced but is still greater than 1, the remainingnis a prime factor itself and is added to the sum. - The main loop replaces the original
nwith this sum and repeats until the sum is equal ton.
This method is highly efficient for the given constraints and does not have the large space or precomputation overhead of the sieve method.
class Solution { public int smallestValue(int n) { while (true) { int sumOfPrimeFactors = getSumOfPrimeFactors(n); if (sumOfPrimeFactors == n) { break; } n = sumOfPrimeFactors; } return n; } private int getSumOfPrimeFactors(int k) { int sum = 0; int n = k; // Find all factors of 2 while (n % 2 == 0) { sum += 2; n /= 2; } // Find factors for odd numbers for (int i = 3; i * i <= n; i += 2) { while (n % i == 0) { sum += i; n /= i; } } // If n is still > 1, it must be a prime number if (n > 1) { sum += n; } // If k was prime initially, sum will be k. If k was 4, sum will be 4. return sum; }}Complexity
Time
O(K * sqrt(N)), where K is the number of iterations and N is the initial input value. Since K is very small, the effective complexity is `O(sqrt(N))`, which is the most efficient for a single call.
Space
O(1) extra space.
Trade-offs
Pros
Very time-efficient for the given constraints.
Requires no extra space, making it memory-efficient.
Strikes a good balance between implementation complexity and performance.
Cons
Slightly more complex to write than the naive trial division.
Solutions
Solution
class Solution {public int smallestValue(int n) { while (true) { int t = n, s = 0; for (int i = 2; i <= n / i; ++i) { while (n % i == 0) { s += i; n /= i; } } if (n > 1) { s += n; } if (s == t) { return s; } n = s; } }}class Solution {public: int smallestValue(int n) { while (1) { int t = n, s = 0; for (int i = 2; i <= n / i; ++i) { while (n % i == 0) { s += i; n /= i; } } if (n > 1) s += n; if (s == t) return s; n = s; } }};class Solution: def smallestValue(self, n: int) -> int: while 1: t, s, i = n, 0, 2 while i <= n // i: while n % i == 0: n //= i s += i i += 1 if n > 1: s += n if s == t: return t n = sVideo walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.