Problem Description
Given an array nums of positive integers, count the number of special subsequences of length 4. A special subsequence is defined by indices (p, q, r, s) that satisfy the following:
- The indices are strictly increasing (p < q < r < s).
- There is at least one element in between each pair of indices (q - p > 1, r - q > 1, and s - r > 1).
- The subsequence meets the multiplication condition: nums[p] * nums[r] == nums[q] * nums[s].
Return the count of such special subsequences.
Key Insights
- The gap constraints force p to be at most q-2 and s to be at least r+2.
- The multiplication condition can be rearranged for matching: for fixed q and r, we want nums[p] * nums[r] == nums[q] * nums[s].
- Instead of using four nested loops (which would be too slow for n ≈ 1000), we can fix the middle indices (q and r) and precompute valid candidates for p (to the left) and s (to the right).
- Use hash maps to count occurrences of potential values for the left (nums[p]) and right (nums[s]) parts. For a fixed pair (q, r), for each valid left value and right value, check if they satisfy:
- left_value * nums[r] == nums[q] * right_value.
- Multiply the frequency counts from the left and right to get the total valid combinations for that fixed middle pair.
Space and Time Complexity
Time Complexity: Roughly O(n^3) in the worst-case if not optimized further, but there is hope to reduce actual runtime through efficient hashing and early filtering. Space Complexity: O(n) to O(n^2) depending on how many entries are stored in the hash maps, but typically O(n) additional space is required.
Solution
The solution fixes two middle indices (q and r) ensuring gap constraints (r - q > 1). For each combination:
- Precompute a hash map (leftCount) for indices p in range [0, q-1] (with p <= q-2) to count occurrences of nums[p].
- Precompute a hash map (rightCount) for indices s in range [r+1, n) that satisfy s - r > 1.
- For each candidate left value (from leftCount), compute the target value for s such that:
- left_value * nums[r] == nums[q] * candidate_right.
- Verify divisibility before performing division.
- Multiply the frequency counts from leftCount and rightCount when the candidate_right exists.
- Sum over all valid (q, r) pairs for the final answer.