hashmap 1726, 3404
Given an array nums of distinct positive integers, return the number of tuples (a, b, c, d) such that a * b = c * d where a, b, c, and d are elements of nums, and a != b != c != d.
Example 1:
Input: nums = [2,3,4,6] Output: 8 Explanation: There are 8 valid tuples: (2,6,3,4) , (2,6,4,3) , (6,2,3,4) , (6,2,4,3) (3,4,2,6) , (4,3,2,6) , (3,4,6,2) , (4,3,6,2)
Example 2:
Input: nums = [1,2,4,5,10] Output: 16 Explanation: There are 16 valid tuples: (1,10,2,5) , (1,10,5,2) , (10,1,2,5) , (10,1,5,2) (2,5,1,10) , (2,5,10,1) , (5,2,1,10) , (5,2,10,1) (2,10,4,5) , (2,10,5,4) , (10,2,4,5) , (10,2,5,4) (4,5,2,10) , (4,5,10,2) , (5,4,2,10) , (5,4,10,2)
Constraints:
1 <= nums.length <= 10001 <= nums[i] <= 104- All elements in
numsare distinct.
class Solution { public int tupleSameProduct(int[] nums) { HashMap<Integer,Integer> map = new HashMap(); for(int i=0;i<nums.length-1;i++){ for(int j=i+1;j<nums.length;j++){ int sum = nums[i]*nums[j]; map.put(sum, map.getOrDefault(sum,0)+1); } } int result = 0; for(int key:map.keySet()){ result += count(map.get(key)); } return result; } private int count(int num){ if(num<2) return 0; if(num==2) return 8; return count(num-1)+8*(num-1); } }
You are given an array nums consisting of positive integers.
A special subsequence is defined as a subsequence of length 4, represented by indices (p, q, r, s), where p < q < r < s. This subsequence must satisfy the following conditions:
nums[p] * nums[r] == nums[q] * nums[s]- There must be at least one element between each pair of indices. In other words,
q - p > 1,r - q > 1ands - r > 1.
A subsequence is a sequence derived from the array by deleting zero or more elements without changing the order of the remaining elements.
Return the number of different special subsequences in nums.
Example 1:
Input: nums = [1,2,3,4,3,6,1]
Output: 1
Explanation:
There is one special subsequence in nums.
(p, q, r, s) = (0, 2, 4, 6):- This corresponds to elements
(1, 3, 3, 1). nums[p] * nums[r] = nums[0] * nums[4] = 1 * 3 = 3nums[q] * nums[s] = nums[2] * nums[6] = 3 * 1 = 3
- This corresponds to elements
Example 2:
Input: nums = [3,4,3,4,3,4,3,4]
Output: 3
Explanation:
There are three special subsequences in nums.
(p, q, r, s) = (0, 2, 4, 6):- This corresponds to elements
(3, 3, 3, 3). nums[p] * nums[r] = nums[0] * nums[4] = 3 * 3 = 9nums[q] * nums[s] = nums[2] * nums[6] = 3 * 3 = 9
- This corresponds to elements
(p, q, r, s) = (1, 3, 5, 7):- This corresponds to elements
(4, 4, 4, 4). nums[p] * nums[r] = nums[1] * nums[5] = 4 * 4 = 16nums[q] * nums[s] = nums[3] * nums[7] = 4 * 4 = 16
- This corresponds to elements
(p, q, r, s) = (0, 2, 5, 7):- This corresponds to elements
(3, 3, 4, 4). nums[p] * nums[r] = nums[0] * nums[5] = 3 * 4 = 12nums[q] * nums[s] = nums[2] * nums[7] = 3 * 4 = 12
- This corresponds to elements
Constraints:
7 <= nums.length <= 10001 <= nums[i] <= 1000
class Solution { /** 思路: nums[p] * nums[r] == nums[q] * nums[s] 可以得到 nums[p] / nums[q] == nums[s] * nums[r] 为降低时间复杂度,我们可以用找出p/q的配对,以及s/r的配对, 分别存入map 然后进行匹配 */ public long numberOfSubsequences(int[] nums) { // 找出p/q的配对,以及s/r的配对, 分别存入map Map<Double, List<int[]>> map1 = new HashMap<>(); Map<Double, List<int[]>> map2 = new HashMap<>(); Set<Double> set = new HashSet<>(); for(int i = 0; i < nums.length; i++) { for(int j = i + 2; j < nums.length; j++) { map1.computeIfAbsent((double)nums[i]/nums[j], key -> new ArrayList<>()) .add(new int[]{i, j}); map2.computeIfAbsent((double)nums[j]/nums[i], key -> new ArrayList<>()) .add(new int[]{i, j}); if(map1.containsKey((double)nums[j]/nums[i])) { set.add((double)nums[j]/nums[i]); } } } long result = 0; // 对于其中公共的key,即为可以组成满足条件的Subsequences for(double key : set) { result += count(map1.get(key), map2.get(key)); } return result; } private long count(List<int[]> list1, List<int[]> list2) { long result = 0; for(int i = 0; i < list1.size(); i++) { int[] curr = list1.get(i); // 找到 大于q + 1 的 s,r 配对 int ind = search(curr[1], list2); // 注意,如果ind满足,那么ind之后的配对都满足,因此个数为:list2.size() - ind if(ind >= 0) result += list2.size() - ind; } return result; } private int search(int target, List<int[]> list) { int left = 0, right = list.size() - 1; int result = -1; while(left <= right) { int mid = left + (right - left) / 2; if(list.get(mid)[0] > target + 1) { result = mid; right = mid - 1; } else { left = mid + 1; } } return result; } }

浙公网安备 33010602011771号