Number of Different Subsequences GCDs - Complete Solution Guide
Number of Different Subsequences GCDs is LeetCode problem 1819, a Hard 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 an array nums that consists of positive integers. The GCD of a sequence of numbers is defined as the greatest integer that divides all the numbers in the sequence evenly. For example, the GCD of the sequence [4,6,16] is 2 . A subsequence of an array is a sequence that can be formed by removing some elements (possibly none) of the array. For example, [2,5,10] is a subsequence of [1,2,1, 2 ,4,1, 5 , 10 ] . Return the number of different GCDs among all non-empty subsequences of nums .
Detailed Explanation
The problem asks us to find the number of distinct greatest common divisors (GCDs) that can be obtained from all non-empty subsequences of a given array of positive integers, `nums`. A subsequence is formed by selecting elements from the original array without changing their order, but possibly skipping some. The GCD of a sequence is the largest positive integer that divides all numbers in the sequence evenly. The goal is to iterate through all possible subsequences, calculate their GCDs, and count the number of *unique* GCDs.
Solution Approach
The solution iterates through all possible GCDs from 1 to the maximum value in the input array. For each potential GCD `g`, it checks if `g` is a valid GCD of some subsequence. This is done by iterating through the multiples of `g` in the range [g, max_num], and checking if each multiple exists in the input `nums`. If a multiple exists, it's included in calculating the GCD of the potential subsequence. If, after iterating through all multiples, the GCD of the considered multiples (divided by `g`) is equal to 1, this confirms that `g` can be a valid subsequence GCD, meaning that the GCD of the multiples is equal to `g` and 'g' exists as a subsequence GCD. The solution keeps track of a boolean array `has_num` to check if each number exists in the input array in O(1) time.
Step-by-Step Algorithm
- Step 1: Find the maximum number (`max_num`) in the input array `nums`. This is needed to determine the range of potential GCDs to check.
- Step 2: Create a boolean array `has_num` of size `max_num + 1` to quickly check if a number exists in the input array `nums`. Initialize it to `false` for all elements.
- Step 3: Iterate through the input array `nums` and set `has_num[num]` to `true` for each number in `nums`.
- Step 4: Initialize a counter `count` to 0. This counter will store the number of distinct subsequence GCDs.
- Step 5: Iterate through all possible GCDs `g` from 1 to `max_num`.
- Step 6: For each `g`, initialize `subsequence_k_gcd` to 0. This variable will store the GCD of the multiples of g, divided by g, that are present in `nums`.
- Step 7: Iterate through the multiples of `g` (starting from `g` up to `max_num`, incrementing by `g` in each step).
- Step 8: Inside the inner loop, check if the current multiple exists in `nums` using the `has_num` array. If `has_num[multiple]` is `true`, it means the multiple is present.
- Step 9: If the multiple is present, update `subsequence_k_gcd` by taking the GCD of the current `subsequence_k_gcd` and `multiple / g`. Note how we are calculating the gcd of the multiples divided by g.
- Step 10: Optimization: If at any point the `subsequence_k_gcd` becomes 1, it means the GCD of the subsequence is exactly `g`, and `g` is a valid subsequence GCD, thus break out of the inner loop. This avoids further unnecessary GCD calculations.
- Step 11: After the inner loop finishes, check if `subsequence_k_gcd` is equal to 1. If it is, increment the `count` because `g` is a valid subsequence GCD.
- Step 12: After the outer loop finishes, return the `count`, which represents the total number of distinct subsequence GCDs.
Key Insights
- Insight 1: The GCD of any subsequence must be a divisor of at least one element in the subsequence, and therefore a divisor of some number in the original array `nums`. This means we only need to consider numbers up to the maximum value in `nums` as potential GCDs.
- Insight 2: For a given potential GCD `g`, we can efficiently check if `g` is a valid GCD of some subsequence by iterating through the multiples of `g` present in `nums`. If `g` is a valid GCD, it must be equal to the GCD of a subsequence consisting of some multiples of `g` from `nums`.
- Insight 3: An optimization can be made: for each potential GCD 'g', once the subsequence GCD derived from its multiples becomes 'g', we know g is a valid GCD, so we can stop computing. This significantly reduces unnecessary calculations
Complexity Analysis
Time Complexity: O(n + mlogm)
Space Complexity: O(m)
Topics
This problem involves: Array, Math, Counting, Number Theory.
Companies
Asked at: Akuna Capital.