Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Minimum removals from array to make GCD Greater in Python
When we have a list of numbers, we may need to remove some elements to increase the GCD (Greatest Common Divisor) of the remaining numbers. This problem asks for the minimum number of removals required to make the GCD larger than the original GCD.
For example, given [6, 9, 15, 30], the initial GCD is 3. After removing 6 and 9, we get [15, 30] with GCD = 15, which is greater than 3. So the answer is 2 removals.
Algorithm Approach
The solution uses prime factorization and the Sieve of Eratosthenes ?
- Find the initial GCD of all numbers
- Divide all numbers by this GCD to normalize them
- Find prime factors of each normalized number
- Count how many numbers share each prime factor
- The minimum removals = total numbers - maximum count of any prime factor
Implementation
from math import gcd as __gcd
INF = 100001
spf = [i for i in range(INF)]
def sieve():
"""Precompute smallest prime factors using Sieve of Eratosthenes"""
for i in range(4, INF, 2):
spf[i] = 2
for i in range(3, INF):
if i**2 > INF:
break
if (spf[i] == i):
for j in range(2 * i, INF, i):
if (spf[j] == j):
spf[j] = i
def calc_fact(x):
"""Find all prime factors of x using precomputed spf array"""
factors = []
while (x != 1):
factors.append(spf[x])
x = x // spf[x]
return factors
def minRemove(numbers, n):
"""Find minimum removals to increase GCD"""
# Find initial GCD
g = 0
for i in range(n):
g = __gcd(numbers[i], g)
# Normalize all numbers by dividing by initial GCD
prime_count = dict()
for i in range(n):
numbers[i] = numbers[i] // g
# Count occurrences of each prime factor
for i in range(n):
prime_factors = calc_fact(numbers[i])
unique_primes = dict()
# Get unique prime factors for this number
for factor in prime_factors:
unique_primes[factor] = 1
# Count each unique prime
for prime in unique_primes:
prime_count[prime] = prime_count.get(prime, 0) + 1
# Find maximum count of any prime factor
minimum_removals = 10**9
for prime in prime_count:
count = prime_count[prime]
removals_needed = n - count
if removals_needed <= minimum_removals:
minimum_removals = removals_needed
return minimum_removals if minimum_removals != 10**9 else -1
# Example usage
numbers = [6, 9, 15, 30]
n = len(numbers)
sieve() # Precompute prime factors
result = minRemove(numbers, n)
print(f"Minimum removals needed: {result}")
Minimum removals needed: 2
How It Works
Let's trace through the example [6, 9, 15, 30] ?
- Initial GCD: gcd(6, 9, 15, 30) = 3
- Normalize: [6÷3, 9÷3, 15÷3, 30÷3] = [2, 3, 5, 10]
-
Prime factors:
- 2 ? [2]
- 3 ? [3]
- 5 ? [5]
- 10 ? [2, 5]
- Prime counts: {2: 2, 3: 1, 5: 2}
- Maximum count: 2 (for primes 2 and 5)
- Minimum removals: 4 - 2 = 2
Key Components
| Function | Purpose | Time Complexity |
|---|---|---|
sieve() |
Precompute smallest prime factors | O(n log log n) |
calc_fact() |
Find prime factors of a number | O(log n) |
minRemove() |
Main algorithm logic | O(n × log max_value) |
Conclusion
This algorithm efficiently finds the minimum removals needed by using prime factorization. The key insight is that numbers sharing prime factors can form a subset with a larger GCD than the original.
