Advertisement

Count the Number of Square-Free Subsets - LeetCode 2572 Solution

Count the Number of Square-Free Subsets - Complete Solution Guide

Count the Number of Square-Free Subsets is LeetCode problem 2572, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

You are given a positive integer 0-indexed array nums . A subset of the array nums is square-free if the product of its elements is a square-free integer . A square-free integer is an integer that is divisible by no square number other than 1 . Return the number of square-free non-empty subsets of the array nums . Since the answer may be too large, return it modulo 10 9 + 7 . A non-empty subset of nums is an array that can be obtained by deleting some (possibly none but not all) elements from nu

Detailed Explanation

The problem asks us to find the number of non-empty subsets of a given array `nums` such that the product of the elements in each subset is a square-free integer. A square-free integer is one that is not divisible by any perfect square other than 1. The elements of the array are positive integers between 1 and 30. We need to return the count of these square-free subsets modulo 10^9 + 7. For example, if `nums = [3, 4, 4, 5]`, the square-free subsets are `[3]`, `[5]`, and `[3, 5]`, giving a total of 3. If `nums = [1]`, the square-free subset is `[1]`, giving a total of 1.

Solution Approach

The solution uses dynamic programming and bit manipulation to efficiently count the number of square-free subsets. First, we precompute a bitmask for each number from 2 to 30, representing the prime factors of the number. If a number is divisible by 4, 9, or 25, we mark it as unsuitable and skip it. The dynamic programming table `dp` has `2^10` entries, where each entry `dp[mask]` stores the number of square-free subsets with the combined prime factors represented by the bitmask `mask`. The DP table is populated iteratively, considering each number in the input array. The number '1' is treated specially by multiplying the final result by 2 raised to the power of the number of 1's in the input array.

Step-by-Step Algorithm

  1. Step 1: Initialize constants like MOD (10^9 + 7) and an array of primes PRIMES less than or equal to 30.
  2. Step 2: Create a mapping `num_to_mask` to store the bitmask representation of each number from 2 to 30. Numbers divisible by 4, 9, or 25 are marked as unsuitable (-1).
  3. Step 3: Count the occurrences of each number in the input array `nums` and store them in `counts` array.
  4. Step 4: Initialize a DP table `dp` of size `2^(number of primes)`. `dp[0]` is set to 1, representing the empty subset.
  5. Step 5: Iterate through numbers from 2 to 30. For each number, if it's suitable and present in the `counts` array, iterate through the DP table in reverse order.
  6. Step 6: If the bitmask of the current number doesn't conflict with the current DP mask, update the DP table by adding the product of `dp[mask]` and the count of the current number to `dp[new_mask]`, where `new_mask` is the bitwise OR of `mask` and the bitmask of the current number. Take modulo MOD.
  7. Step 7: Calculate the sum of all entries in the DP table (excluding dp[0] to avoid an empty set only containing 1's).
  8. Step 8: Calculate 2 raised to the power of the number of 1's in the `nums` array. This accounts for all possible combinations of the number 1.
  9. Step 9: Multiply the sum calculated in Step 7 by the result from Step 8 and take modulo MOD.
  10. Step 10: Subtract 1 from the result (because problem statement does not want empty subset) and take modulo MOD to get the final answer.

Key Insights

  • Insight 1: The numbers in the input array are between 1 and 30. Since the square factors to avoid are 4, 9, and 25, any number divisible by one of those can't be part of a square-free subset with itself. This allows us to pre-compute which numbers are unsuitable and ignore them.
  • Insight 2: We can represent each number in the array as a bitmask, where each bit corresponds to a prime number less than 30 (2, 3, 5, 7, 11, 13, 17, 19, 23, 29). A set is square-free if no prime appears more than once in its product. Bitwise OR operations allow us to combine the prime factors of the numbers and keep track of which primes are already present.
  • Insight 3: Dynamic Programming can be used to count the number of square-free subsets. The DP state can be represented by a bitmask indicating which prime factors are already used in the current subset. The number 1 needs special handling as it can be combined freely without affecting the square-free property.

Complexity Analysis

Time Complexity: O(n * 2^10)

Space Complexity: O(2^10)

Topics

This problem involves: Array, Math, Dynamic Programming, Bit Manipulation, Bitmask.

Companies

Asked at: Media.net.