美数对
难度:
标签:
题目描述
代码结果
运行时间: 146 ms, 内存: 36.7 MB
/*
* Leetcode 2613: 美数对
* 题目思路:
* 给定一个整数数组 nums 和一个整数 k,求满足以下条件的元素对 (i, j) 的数量:
* 1. 0 <= i < j < nums.length
* 2. nums[i] == nums[j]
* 3. (i * j) % k == 0
*/
import java.util.stream.IntStream;
public class BeautifulPairsStream {
public int countBeautifulPairs(int[] nums, int k) {
return (int) IntStream.range(0, nums.length)
.flatMap(i -> IntStream.range(i + 1, nums.length)
.filter(j -> nums[i] == nums[j] && (i * j) % k == 0))
.count();
}
public static void main(String[] args) {
BeautifulPairsStream bp = new BeautifulPairsStream();
int[] nums = {1, 2, 3, 1, 1, 3};
int k = 2;
System.out.println(bp.countBeautifulPairs(nums, k)); // Output: 2
}
}
解释
方法:
该题解使用分治法和归并排序的思想来解决问题。首先将所有点按照 x 坐标排序,然后递归地将点集划分为左右两个子集,分别求解子问题。在合并时,对于横跨左右子集的点对,可以通过维护一个纵坐标有序的点集,在一定范围内枚举所有可能的点对,更新全局最优解。最后返回距离最小的一对点的下标。
时间复杂度:
O(nlog^2n)
空间复杂度:
O(nlogn)
代码细节讲解
🦆
在分治法中,为什么选择以x坐标来排序并划分点集,而不是选择y坐标或其他属性?
▷🦆
递归处理过程中,当点集只有一个点时返回的是 inf, -1, -1,这样的返回值是如何在上层递归中被处理的?
▷🦆
对于横跨左右子集的点对,为什么确定纵坐标的差值不超过d1就可以停止枚举?这样是否可能漏掉某些有效的点对?
▷