diff --git a/tutorials/math/prime-factors.md b/tutorials/math/prime-factors.md
index 5cb1155a257..30ebbf24e3a 100644
--- a/tutorials/math/prime-factors.md
+++ b/tutorials/math/prime-factors.md
@@ -1,15 +1,13 @@
---
title: 'Prime Factors'
description: 'Factor of a given number which is a prime number.'
-hide_table_of_contents: true
-draft: true
keywords:
- leetcode
- tutorial
- prime factors
---
-
+
## Overview
@@ -31,7 +29,7 @@ We can further speed up our algorithm by using the fact that a number can have a
Since $P > \sqrt n$ and $Q > \sqrt n$ $\implies$ $P \cdot Q > \sqrt n \cdot \sqrt n (= n^2)$. This is not possible as $P$ and $Q$ are prime factor of $N$ so their product must be less than or equal to $N$.
-## Implementation #1
+## Implementation
@@ -41,7 +39,6 @@ Since $P > \sqrt n$ and $Q > \sqrt n$ $\implies$ $P \cdot Q > \sqrt n \cdot \sq
```cpp
vector getPrimeFactors(int n) {
vector prime_factors;
-
// i * i <= n or i <= sqrt(n) both work.
for (int i = 2; i * i <= n; i++) {
while (n % i == 0) {
@@ -49,7 +46,6 @@ vector getPrimeFactors(int n) {
n /= i;
}
}
-
if (n > 1) prime_factors.emplace_back(n);
return prime_factors;
}
@@ -79,7 +75,6 @@ Since the pre computation takes $O(MAX)$ time so we cannot find prime factors of
// For sake of simplicity let us assume min_prime is a global vector.
vector getPrimeFactorsInLogn(int n) {
vector prime_factors;
-
while (n > 1) {
int smallest_prime_factor_of_n = min_prime[n];
prime_factors.push_back(smallest_prime_factor_of_n);
@@ -100,19 +95,15 @@ vector getPrimeFactorsInLogn(int n) {
```cpp
vector minPrime(int MAX) {
vector min_prime(MAX + 1);
-
// Set min_prime[i] = i
- iota(std::begin(min_prime), std::end(min_prime), 0);
-
+ iota(begin(min_prime), end(min_prime), 0);
for (int i = 2; i * i <= MAX; i++) {
if (min_prime[i] != i) continue;
-
// if min_prime[i] = i then i must be a prime number.
// Any multiple of i less than i * i (i.e., i * 2, i * 3, ... i * (i - 1)) has a smaller prime factor than i.
// Any number >= i * i may have i as it's minimum prime factor
- for (int j = i * i; j <= MAX; j += i) min_prime[j] = std::min(min_prime[j], i);
+ for (int j = i * i; j <= MAX; j += i) min_prime[j] = min(min_prime[j], i);
}
-
return min_prime;
}
```
@@ -139,7 +130,6 @@ int distinctPrimeFactors(vector& nums) {
auto pf = getPrimeFactors(num);
for (auto prime : pf) distinct_pf.emplace(prime);
}
-
return distinct_pf.size();
}
```
@@ -160,42 +150,36 @@ We can code same approach using `getPrimeFactorsInLogn()` function (Method-2).
class Solution {
vector minPrime(int MAX) {
vector min_prime(MAX + 1);
- iota(std::begin(min_prime), std::end(min_prime), 0);
-
+ iota(begin(min_prime), end(min_prime), 0);
for (int i = 2; i * i <= MAX; i++) {
if (min_prime[i] != i) continue;
- for (int j = i * i; j <= MAX; j += i) min_prime[j] = std::min(min_prime[j], i);
+ for (int j = i * i; j <= MAX; j += i) min_prime[j] = min(min_prime[j], i);
}
-
return min_prime;
}
// We need to pass the min_prime vector to use inside the function.
- vector getPrimeFactorsInLogn(int n, std::vector &min_prime) {
+ vector getPrimeFactorsInLogn(int n, vector &min_prime) {
vector prime_factors;
-
while (n > 1) {
int smallest_prime_factor_of_n = min_prime[n];
prime_factors.push_back(smallest_prime_factor_of_n);
n /= smallest_prime_factor_of_n;
}
-
return prime_factors;
}
+
public:
int distinctPrimeFactors(vector& nums) {
set distinct_pf;
-
// Finding the limit upto which we should run sieve.
const int max = *max_element(begin(nums), end(nums));
auto min_prime = minPrime(max + 1);
-
for (auto num : nums) {
// Get prime factors of each number in log(n) time.
auto pf = getPrimeFactorsInLogn(num, min_prime);
for (auto prime : pf) distinct_pf.emplace(prime);
}
-
return distinct_pf.size();
}
};
@@ -238,18 +222,31 @@ Adding $(1)$ and $(2)$ we get, $2 \cdot (A \cdot B) \geq 2 \cdot (A + B) \implie
```cpp
-int smallestValue(int n) {
- while (true)
- {
- auto pf = getPrimeFactors(n);
- int sum = accumulate(begin(pf), end(pf), 0);
-
- if (sum == n) break;
- n = sum;
+class Solution {
+public:
+ vector getPrimeFactors(int n) {
+ vector prime_factors;
+ // i * i <= n or i <= sqrt(n) both work.
+ for (int i = 2; i * i <= n; i++) {
+ while (n % i == 0) {
+ prime_factors.emplace_back(i);
+ n /= i;
+ }
+ }
+ if (n > 1) prime_factors.emplace_back(n);
+ return prime_factors;
}
- return n;
-}
+ int smallestValue(int n) {
+ while (true) {
+ auto pf = getPrimeFactors(n);
+ int sum = accumulate(begin(pf), end(pf), 0);
+ if (sum == n) break;
+ n = sum;
+ }
+ return n;
+ }
+};
```
@@ -294,85 +291,68 @@ class Solution {
// g = graph using which we can find maximum connected component size
vector isPresent;
vector> g;
-
vector minPrime(int MAX) {
vector min_prime(MAX + 1);
- iota(std::begin(min_prime), std::end(min_prime), 0);
-
+ iota(begin(min_prime), end(min_prime), 0);
for (int i = 2; i * i <= MAX; i++) {
if (min_prime[i] != i) continue;
- for (int j = i * i; j <= MAX; j += i) min_prime[j] = std::min(min_prime[j], i);
+ for (int j = i * i; j <= MAX; j += i) min_prime[j] = min(min_prime[j], i);
}
-
return min_prime;
}
- vector getPrimeFactorsInLogn(int n, std::vector &min_prime) {
+ vector getPrimeFactorsInLogn(int n, vector &min_prime) {
vector prime_factors;
-
while (n > 1) {
int smallest_prime_factor_of_n = min_prime[n];
-
// Since we only need unique prime factors so we won't push same number again and again
if (n % smallest_prime_factor_of_n == 0) prime_factors.push_back(smallest_prime_factor_of_n);
-
// Remove the prime factor completely from n
while (n % smallest_prime_factor_of_n == 0) n /= smallest_prime_factor_of_n;
}
-
return prime_factors;
}
- int getComponentSize(int src, std::vector &vis) {
+ int getComponentSize(int src, vector &vis) {
queue q;
q.emplace(src);
vis[src] = true;
int count = isPresent[src];
-
while (!q.empty()) {
int node = q.front();
q.pop();
-
for (int child : g[node]) {
if (!vis[child]) {
q.emplace(child);
vis[child] = true;
-
// Increase component size only if the number is present in nums.
count += isPresent[child];
}
}
}
-
return count;
}
public:
int largestComponentSize(vector& nums) {
int max_elem = *max_element(begin(nums), end(nums));
auto min_prime = minPrime(max_elem + 1);
-
isPresent.resize(max_elem + 1);
g.resize(max_elem + 1);
vector vis(max_elem + 1);
-
for (int num : nums) {
isPresent[num] = 1;
auto pf = getPrimeFactorsInLogn(num, min_prime);
-
for (auto prime : pf) {
if (prime == num) continue;
-
// num and prime has gcd > 1
g[prime].emplace_back(num);
g[num].emplace_back(prime);
}
}
-
int ans = isPresent[1];
for (int src = 2; src <= max_elem; src++) {
ans = max(ans, getComponentSize(src, vis));
}
-
return ans;
}
};