Taro Logo

Distinct Prime Factors of Product of Array

Medium
2 views
2 months ago

Given an array of positive integers nums, return the number of distinct prime factors in the product of the elements of nums.

Note that:

  • A number greater than 1 is called prime if it is divisible by only 1 and itself.
  • An integer val1 is a factor of another integer val2 if val2 / val1 is an integer.

Example 1:

Input: nums = [2,4,3,7,10,6]
Output: 4
Explanation:
The product of all the elements in nums is: 2 * 4 * 3 * 7 * 10 * 6 = 10080 = 25 * 32 * 5 * 7.
There are 4 distinct prime factors so we return 4.

Example 2:

Input: nums = [2,4,8,16]
Output: 1
Explanation:
The product of all the elements in nums is: 2 * 4 * 8 * 16 = 1024 = 210.
There is 1 distinct prime factor so we return 1.

Constraints:

  • 1 <= nums.length <= 104
  • 2 <= nums[i] <= 1000
Sample Answer
## Distinct Prime Factors

Given an array of positive integers `nums`, the task is to find the number of distinct prime factors in the product of the elements of `nums`.

### Naive Approach

1.  Calculate the product of all elements in `nums`. This can be done with a simple loop.
2.  Find all prime factors of the product. This can be done by iterating from 2 up to the square root of the product. If a number `i` divides the product, then `i` is a factor. Keep dividing the product by `i` until it is no longer divisible.
3.  Store the distinct prime factors in a set to avoid duplicates.
4.  Return the size of the set.

```python
def distinctPrimeFactorsNaive(nums):
    product = 1
    for num in nums:
        product *= num

    prime_factors = set()
    d = 2
    while d * d <= product:
        while product % d == 0:
            prime_factors.add(d)
            product //= d
        d += 1
    if product > 1:
        prime_factors.add(product)

    return len(prime_factors)

# Example usage:
nums1 = [2, 4, 3, 7, 10, 6]
print(f"Distinct prime factors of {nums1}: {distinctPrimeFactorsNaive(nums1)}")  # Output: 4

nums2 = [2, 4, 8, 16]
print(f"Distinct prime factors of {nums2}: {distinctPrimeFactorsNaive(nums2)}")  # Output: 1

Explanation:

  • We iterate through the nums array to calculate the product of all numbers.
  • We then iterate from d = 2 up to the square root of the product to find prime factors. If d divides the product, we add d to the prime_factors set and keep dividing the product by d until it's no longer divisible.
  • After the loop, if product is still greater than 1, it means the remaining value is also a prime factor, so we add it to the set.
  • Finally, we return the number of distinct prime factors.

Optimal Approach

Instead of calculating the product first, we can find the prime factors of each number in the input array and add them to a set. This avoids dealing with potentially very large products.

  1. Create an empty set to store distinct prime factors.
  2. Iterate through each number in nums.
  3. For each number, find its prime factors and add them to the set.
  4. Return the size of the set.
def distinctPrimeFactorsOptimal(nums):
    prime_factors = set()

    for num in nums:
        d = 2
        temp_num = num
        while d * d <= temp_num:
            while temp_num % d == 0:
                prime_factors.add(d)
                temp_num //= d
            d += 1
        if temp_num > 1:
            prime_factors.add(temp_num)

    return len(prime_factors)

# Example usage:
nums1 = [2, 4, 3, 7, 10, 6]
print(f"Distinct prime factors of {nums1}: {distinctPrimeFactorsOptimal(nums1)}")  # Output: 4

nums2 = [2, 4, 8, 16]
print(f"Distinct prime factors of {nums2}: {distinctPrimeFactorsOptimal(nums2)}")  # Output: 1

Explanation:

  • We iterate through each num in the nums array.
  • For each num, we find its prime factors by iterating from d = 2 up to the square root of num. If d divides num, we add d to the prime_factors set and keep dividing num by d until it's no longer divisible.
  • After the inner loop, if num is still greater than 1, it means the remaining value is also a prime factor, so we add it to the set.
  • Finally, we return the number of distinct prime factors.

Big(O) Run-time Analysis

  • Naive Approach:
    • Calculating the product: O(n), where n is the number of elements in nums.
    • Finding prime factors: O(sqrt(product)), where product is the product of all elements in nums. In the worst case, this can be very large.
    • Overall: O(n + sqrt(product))
  • Optimal Approach:
    • Iterating through each number in nums: O(n), where n is the number of elements in nums.
    • Finding prime factors for each number: O(sqrt(max(nums))), where max(nums) is the largest number in nums. Since nums[i] <= 1000, this is O(sqrt(1000)) which is constant.
    • Overall: O(n * sqrt(max(nums))) which simplifies to O(n) because sqrt(max(nums)) is bounded by a constant (sqrt(1000)).

Big(O) Space Usage Analysis

  • Naive Approach:
    • prime_factors set: In the worst case, the number of distinct prime factors can be log(product), so the space complexity is O(log(product)).
  • Optimal Approach:
    • prime_factors set: In the worst case, the number of distinct prime factors can be at most the number of elements in nums, since each number could potentially have a unique prime factor. So the space complexity is O(n).

Edge Cases

  1. Empty Input Array: If the input array nums is empty, the product is considered 1, and there are no prime factors. The code should return 0.
  2. Input Array with 1: If the input array contains 1, it does not affect the product or the prime factors. The code should handle this correctly.
  3. Large Input Numbers: The input numbers are constrained to be between 2 and 1000. If the numbers were significantly larger, the sqrt computation might become more expensive, but for this constraint, it's acceptable.
def distinctPrimeFactorsOptimal(nums):
    if not nums:
        return 0

    prime_factors = set()

    for num in nums:
        d = 2
        temp_num = num
        while d * d <= temp_num:
            while temp_num % d == 0:
                prime_factors.add(d)
                temp_num //= d
            d += 1
        if temp_num > 1:
            prime_factors.add(temp_num)

    return len(prime_factors)