You are given an integer array queries of length n.
Return the prime factorization of each number in array queries in sorted order.
Input : queries = [2, 3, 4, 5, 6]
Output : [ [2], [3], [2, 2], [5], [2, 3] ]
Explanation : The values 2, 3, 5 are itself prime numbers.
The prime factorization of 4 will be --> 2 * 2.
The prime factorization of 6 will be --> 2 * 3.
Input : queries = [7, 12, 18]
Output : [ [7], [2, 2, 3], [2, 3, 3] ]
Explanation : The value 7 itself is a prime number.
The prime factorization of 12 will be --> 2 * 2 * 3.
The prime factorization of 18 will be --> 2 * 3 * 3.
Input : queries = [15, 20]
A naive approach to find the prime factorization of a given number is by dividing the number multiple times with the smallest prime number that divides it until the number becomes 1.
The prime factorisation for a number can be found in the following manner:
#include <bits/stdc++.h>
using namespace std;
class Solution{
private:
/* Helper function to find the prime
factorization of a number */
vector<int> primeFact(int n) {
// To store the result
vector<int> ans;
/* Keep dividing the number with
2 till it is possible */
while (n % 2 == 0) {
// Add 2 to result
ans.push_back(2);
// Update the number
n = n/2;
}
/* Start iterating from 3 skipping
one number (because n is now odd) */
for (int i=3; i <= sqrt(n); i += 2) {
// While i divides n
while (n % i == 0) {
// Store the number
ans.push_back(i);
// Update the number
n = n/i;
}
}
// Edge case
if (n > 2) ans.push_back(n);
// Return the result
return ans;
}
public:
/* Function to get the prime
factorization of all the number */
vector<vector<int>> primeFactors(vector<int>& queries){
// To store the answer
vector<vector<int>> ans;
// Iterate on each number in query
for(int i=0; i < queries.size(); i++) {
/* Function call to get the prime
factorization of current number */
ans.push_back(primeFact(queries[i]));
}
// Return the answer
return ans;
}
};
int main() {
vector<int> queries = {2, 3, 4, 5, 6};
/* Creating an instance of
Solution class */
Solution sol;
// Function call to get all primes till N
vector<vector<int>> ans = sol.primeFactors(queries);
cout << "The prime factorization of all the numbers is: " << endl;
for(int i=0; i < ans.size(); i++) {
cout << "For " << queries[i] << ": ";
for(int j=0; j < ans[i].size(); j++) {
cout << ans[i][j] << " ";
}
cout << endl;
}
return 0;
}
import java.util.*;
class Solution {
/* Helper function to find the prime
factorization of a number */
private List<Integer> primeFact(int n) {
// To store the result
List<Integer> ans = new ArrayList<>();
/* Keep dividing the number with
2 till it is possible */
while (n % 2 == 0) {
// Add 2 to result
ans.add(2);
// Update the number
n = n / 2;
}
/* Start iterating from 3 skipping
one number (because n is now odd) */
for (int i = 3; i <= Math.sqrt(n); i += 2) {
// While i divides n
while (n % i == 0) {
// Store the number
ans.add(i);
// Update the number
n = n / i;
}
}
// Edge case
if (n > 2) ans.add(n);
// Return the result
return ans;
}
/* Function to get the prime
factorization of all the number */
public List<List<Integer>> primeFactors(int[] queries) {
// To store the answer
List<List<Integer>> ans = new ArrayList<>();
// Iterate on each number in query
for (int i = 0; i < queries.length; i++) {
/* Function call to get the prime
factorization of current number */
ans.add(primeFact(queries[i]));
}
// Return the answer
return ans;
}
public static void main(String[] args) {
int[] queries = {2, 3, 4, 5, 6};
// Creating an instance of Solution class
Solution sol = new Solution();
// Function call to get all primes till N
List<List<Integer>> ans = sol.primeFactors(queries);
// Output
System.out.println("The prime factorization of all the numbers is: ");
for (int i = 0; i < ans.size(); i++) {
System.out.print("For " + queries[i] + ": ");
for (int j = 0; j < ans.get(i).size(); j++) {
System.out.print(ans.get(i).get(j) + " ");
}
System.out.println();
}
}
}
import math
class Solution:
# Helper function to find the prime
# factorization of a number
def primeFact(self, n):
# To store the result
ans = []
# Keep dividing the number
# with 2 till it is possible
while n % 2 == 0:
# Add 2 to result
ans.append(2)
# Update the number
n = n // 2
# Start iterating from 3 skipping
# one number (because n is now odd)
for i in range(3, int(math.sqrt(n)) + 1, 2):
# While i divides n
while n % i == 0:
# Store the number
ans.append(i)
# Update the number
n = n // i
# Edge case
if n > 2:
ans.append(n)
# Return the result
return ans
# Function to get the prime
# factorization of all the number
def primeFactors(self, queries):
# To store the answer
ans = []
# Iterate on each number in query
for i in range(len(queries)):
# Function call to get the prime
# factorization of current number
ans.append(self.primeFact(queries[i]))
# Return the answer
return ans
# Main code
if __name__ == "__main__":
queries = [2, 3, 4, 5, 6]
# Creating an instance of Solution class
sol = Solution()
# Function call to get all primes till N
ans = sol.primeFactors(queries)
print("The prime factorization of all the numbers is: ")
for i in range(len(ans)):
print(f"For {queries[i]}: ", end="")
for j in range(len(ans[i])):
print(ans[i][j], end=" ")
print()
class Solution {
// Helper function to find the prime factorization of a number
primeFact(n) {
// To store the result
let ans = [];
// Keep dividing the number with 2 till it is possible
while (n % 2 === 0) {
// Add 2 to result
ans.push(2);
// Update the number
n = Math.floor(n / 2);
}
/* Start iterating from 3 skipping one
number (because n is now odd) */
for (let i = 3; i <= Math.sqrt(n); i += 2) {
// While i divides n
while (n % i === 0) {
// Store the number
ans.push(i);
// Update the number
n = Math.floor(n / i);
}
}
// Edge case
if (n > 2) ans.push(n);
// Return the result
return ans;
}
/* Function to get the prime
factorization of all the number */
primeFactors(queries) {
// To store the answer
let ans = [];
// Iterate on each number in query
for (let i = 0; i < queries.length; i++) {
/* Function call to get the prime
factorization of current number */
ans.push(this.primeFact(queries[i]));
}
// Return the answer
return ans;
}
}
// Main code
const queries = [2, 3, 4, 5, 6];
// Creating an instance of Solution class
const sol = new Solution();
// Function call to get all primes till N
const ans = sol.primeFactors(queries);
console.log("The prime factorization of all the numbers is: ");
for (let i = 0; i < ans.length; i++) {
console.log(`For ${queries[i]}: `, ans[i].join(" "));
}
Time Complexity: O(N x num1/2) (where N represents the number of queries and num represents the average of all the numbers in queries)
The PrimeFact(num) function has the time complexity of O(num1/2):
Space Complexity: O(N x log2(num))
Using a list to store the prime factorization of a number takes up O(log2(num)) space. Thus, for N numbers, the total space requirement is O(N x log2(num)).
The optimal solution aims to efficiently find the prime factorization of each number in a given array. Unlike the naive approach that repeatedly divides by potential factors, this solution precomputes the smallest prime factor for every number up to a maximum value using the Sieve of Eratosthenes. This optimization significantly reduces the time complexity when querying prime factorizations for multiple numbers.
The use of the Sieve of Eratosthenes allows for the precomputation of prime factors, making the prime factorization query for each number extremely fast.
#include <bits/stdc++.h>
using namespace std;
#define MAX_N 100000
/* To store the smallest prime factors for
all number with all nodes initially
having smallest prime factor as 1 */
vector<int> SPF(MAX_N + 1, 1);
class Solution{
private:
/* Function to precompute smallest prime
factor using sieve of eratosthenes */
void sieve() {
// Iterate on all the number
for (int i = 2; i <= MAX_N; i++) {
// If the number is a prime number
if (SPF[i] == 1) {
/* Mark all its multiples who have not
received their smallest prime factor yet*/
for (int j = i; j <= MAX_N; j += i) {
// If smallest prime factor not received yet
if (SPF[j]== 1) {
/* Store i as the smallest
prime factor for its multiple */
SPF[j] = i;
}
}
}
}
// Return
return;
}
/* Helper function to find the prime
factorization of a number */
vector<int> primeFact(int n) {
// To store the result
vector<int> ans;
// Until the number is not reduced to 1
while (n != 1) {
// Add the smallest prime factor to the list
ans.push_back(SPF[n]);
// Update the number
n = n / SPF[n];
}
// Return the result
return ans;
}
public:
/* Function to get the prime
factorization of all the number */
vector<vector<int>> primeFactors(vector<int>& queries){
/* Pre compute the smallest
possible factor for all numbers */
sieve();
// To store the answer
vector<vector<int>> ans;
// Iterate on each number in query
for(int i=0; i < queries.size(); i++) {
/* Function call to get the prime
factorization of current number */
ans.push_back(primeFact(queries[i]));
}
// Return the answer
return ans;
}
};
int main() {
vector<int> queries = {2, 3, 4, 5, 6};
/* Creating an instance of
Solution class */
Solution sol;
// Function call to get all primes till N
vector<vector<int>> ans = sol.primeFactors(queries);
cout << "The prime factorization of all the numbers is: " << endl;
for(int i=0; i < ans.size(); i++) {
cout << "For " << queries[i] << ": ";
for(int j=0; j < ans[i].size(); j++) {
cout << ans[i][j] << " ";
}
cout << endl;
}
return 0;
}
import java.util.*;
class Solution {
private static final int MAX_N = 100000;
/* To store the smallest prime factors for
all number with all nodes initially
having smallest prime factor as 1 */
private int[] SPF = new int[MAX_N + 1];
/* Constructor to initialize the smallest prime factor array */
public Solution() {
Arrays.fill(SPF, 1);
}
/* Function to precompute smallest prime
factor using sieve of eratosthenes */
private void sieve() {
// Iterate on all the number
for (int i = 2; i <= MAX_N; i++) {
// If the number is a prime number
if (SPF[i] == 1) {
/* Mark all its multiples who have not
received their smallest prime factor yet*/
for (int j = i; j <= MAX_N; j += i) {
// If smallest prime factor not received yet
if (SPF[j] == 1) {
/* Store i as the smallest
prime factor for its multiple */
SPF[j] = i;
}
}
}
}
}
/* Helper function to find the prime
factorization of a number */
private List<Integer> primeFact(int n) {
// To store the result
List<Integer> ans = new ArrayList<>();
// Until the number is not reduced to 1
while (n != 1) {
// Add the smallest prime factor to the list
ans.add(SPF[n]);
// Update the number
n = n / SPF[n];
}
// Return the result
return ans;
}
/* Function to get the prime
factorization of all the number */
public List<List<Integer>> primeFactors(int[] queries) {
/* Precompute the smallest
possible factor for all numbers */
sieve();
// To store the answer
List<List<Integer>> ans = new ArrayList<>();
// Iterate on each number in query
for (int query : queries) {
/* Function call to get the prime
factorization of current number */
ans.add(primeFact(query));
}
// Return the answer
return ans;
}
public static void main(String[] args) {
int[] queries = {2, 3, 4, 5, 6};
/* Creating an instance of
Solution class */
Solution sol = new Solution();
// Function call to get all primes till N
List<List<Integer>> ans = sol.primeFactors(queries);
System.out.println("The prime factorization of all the numbers is: ");
for (int i = 0; i < ans.size(); i++) {
System.out.print("For " + queries[i] + ": ");
for (int factor : ans.get(i)) {
System.out.print(factor + " ");
}
System.out.println();
}
}
}
MAX_N = 100000
# To store the smallest prime factors for
# all number with all nodes initially
# having smallest prime factor as 1
SPF = [1] * (MAX_N + 1)
class Solution:
def __init__(self):
self.sieve()
# Function to precompute smallest prime
# factor using sieve of eratosthenes
def sieve(self):
# Iterate on all the number
for i in range(2, MAX_N + 1):
# If the number is a prime number
if SPF[i] == 1:
# Mark all its multiples who have not
# received their smallest prime factor yet
for j in range(i, MAX_N + 1, i):
# If smallest prime factor not received yet
if SPF[j] == 1:
# Store i as the smallest
# prime factor for its multiple
SPF[j] = i
# Helper function to find the prime
# factorization of a number
def primeFact(self, n):
# To store the result
ans = []
# Until the number is not reduced to 1
while n != 1:
# Add the smallest prime factor to the list
ans.append(SPF[n])
# Update the number
n = n // SPF[n]
# Return the result
return ans
# Function to get the prime
# factorization of all the number
def primeFactors(self, queries):
# To store the answer
ans = []
# Iterate on each number in query
for query in queries:
# Function call to get the prime
# factorization of current number
ans.append(self.primeFact(query))
# Return the answer
return ans
if __name__ == "__main__":
queries = [2, 3, 4, 5, 6]
# Creating an instance of
# Solution class
sol = Solution()
# Function call to get all primes till N
ans = sol.primeFactors(queries)
print("The prime factorization of all the numbers is: ")
for i in range(len(ans)):
print(f"For {queries[i]}: ", end="")
for factor in ans[i]:
print(factor, end=" ")
print()
const MAX_N = 100000;
/* To store the smallest prime factors for
all number with all nodes initially
having smallest prime factor as 1 */
const SPF = new Array(MAX_N + 1).fill(1);
class Solution {
constructor() {
this.sieve();
}
/* Function to precompute smallest prime
factor using sieve of eratosthenes */
sieve() {
// Iterate on all the number
for (let i = 2; i <= MAX_N; i++) {
// If the number is a prime number
if (SPF[i] === 1) {
/* Mark all its multiples who have not
received their smallest prime factor yet */
for (let j = i; j <= MAX_N; j += i) {
// If smallest prime factor not received yet
if (SPF[j] === 1) {
/* Store i as the smallest prime
factor for its multiple */
SPF[j] = i;
}
}
}
}
}
/* Helper function to find the prime
factorization of a number */
primeFact(n) {
// To store the result
const ans = [];
// Until the number is not reduced to 1
while (n !== 1) {
// Add the smallest prime factor to the list
ans.push(SPF[n]);
// Update the number
n = n / SPF[n];
}
// Return the result
return ans;
}
/* Function to get the prime
factorization of all the number */
primeFactors(queries) {
// To store the answer
const ans = [];
// Iterate on each number in query
for (let i = 0; i < queries.length; i++) {
/* Function call to get the prime
factorization of current number */
ans.push(this.primeFact(queries[i]));
}
// Return the answer
return ans;
}
}
const queries = [2, 3, 4, 5, 6];
/* Creating an instance of
Solution class */
const sol = new Solution();
// Function call to get all primes till N
const ans = sol.primeFactors(queries);
console.log("The prime factorization of all the numbers is: ");
for (let i = 0; i < ans.length; i++) {
console.log(`For ${queries[i]}: ${ans[i].join(" ")}`);
}
Time Complexity: O(max_N x log(log(max_N))) + O(N x log(num)) (where N represent the number of queries, num represents the average number in the queries and max_N = 105)
Space Complexity: O(max_N) + O(N x log(num))
The SPF array takes O(max_N) space and the space taken by list to store the result is O(N x log(num)).
Q: Why use SPF instead of brute-force division?
A: The Smallest Prime Factor (SPF) array allows factorization in O(log m) per number by iteratively dividing by precomputed smallest primes. Brute-force checking requires O(√m) per number, which is slower.
Q: Can we use the Sieve of Eratosthenes directly for factorization?
A: Standard Sieve finds primes, but Modified Sieve precomputes SPF, allowing faster factorization.
Q: How does this compare to Pollard’s Rho algorithm for factorization?
A: Pollard’s Rho is used for extremely large numbers (e.g., 10¹⁸+), whereas SPF is best for numbers ≤ 10⁶.
Q: How would you modify this approach to return factors with their exponents (e.g., {2:3, 5:1} for 40)?
A: Instead of storing factors in a list, use a dictionary to count occurrences.