题目
题目链接
分析
一种暴力的方法,枚举数组所有数字,分别计算当前元素前面不同的元素和后面不同的元素,然后相减即可。这样的话太暴力,前缀和后缀也需要分别遍历:O(N*2)了。
我们来优化一下:
-
根据这种暴力方法,我们可以利用一下 Set 的特性,Set 集合里面每一个元素都是唯一的。
-
后续遍历数组,记录每个后缀不同的不同元素的个数就是set的大小,然后把元素放入 set 里面,组成数组 sufCnt,这就把当前元素i的后缀不同元素的个数求出来了 sufCnt[i]。
-
然后就是求 前元素i的前缀不同元素的个数,其实和求后缀一样, 防止多创建一个 set 集合,我们直接把之前的 set 集合清空 。
-
正序遍历数组,把元素放入 set 里面,然后记录每个前缀不同的不同元素的个数就是set的大小,然后减去 sufCnt[i]即可,就是题目想要求的值。
代码
class Solution {
public int[] distinctDifferenceArray(int[] nums) {
int n = nums.length;
// 存放最终结果
int[] res = new int[n];
// 存放后缀
int[] sufCnt = new int[n];
Set<Integer> set = new HashSet<>();
for(int i = n - 1;i >= 0;i --) {
sufCnt[i] = set.size();
set.add(nums[i]);
}
// 清空 set 集合
set.clear();
for(int i = 0;i < n;i ++) {
set.add(nums[i]);
res[i] = set.size() - sufCnt[i];
}
return res;
}
}