如何以近似O(N)时间复杂度找出数组中的最大非重复值?
如何以近似O(N)时间复杂度找出数组中的最大非重复值?
我尝试了很久,只想到了时间复杂度近似O(2N)的解法,代码如下:
int solution(int[] A) { List<Integer> arr = new ArrayList<Integer>(); Set<Integer> set = new HashSet<Integer>(); int max = 0; for(int i = 0; i < A.length; i++) { if(!set.add(A[i])) arr.add(A[i]); } for(int i = 0; i < A.length; i++) { if (max < A[i] && !arr.contains(A[i])) max = A[i]; } return max; }请问是否有更快的实现方式?
首先得给你提个醒:你当前的解法实际时间复杂度是O(N²),不是你以为的O(2N)。问题出在第二个循环里的arr.contains(A[i])——这是线性查找,每次调用都要遍历整个arr,最坏情况下(比如数组所有元素都唯一),这部分的开销会变成O(N*N),整体复杂度直接飙升。
要实现真正的O(N)时间复杂度,我们可以用哈希表统计元素出现次数的思路,把判断元素是否唯一的操作从O(N)降到平均O(1),具体步骤如下:
- 遍历数组一次,用HashMap记录每个元素的出现次数;
- 再次遍历数组(或直接遍历HashMap),筛选出出现次数为1的最大元素。
整个过程两次线性遍历,哈希表的增、查操作都是平均O(1),所以整体时间复杂度是严格的O(N)。
下面是优化后的Java代码:
int solution(int[] A) { Map<Integer, Integer> countMap = new HashMap<>(); // 统计每个元素的出现次数 for (int num : A) { countMap.put(num, countMap.getOrDefault(num, 0) + 1); } int maxUnique = Integer.MIN_VALUE; // 遍历数组找最大的唯一元素 for (int num : A) { if (countMap.get(num) == 1 && num > maxUnique) { maxUnique = num; } } // 处理没有唯一元素的情况,可根据实际需求调整返回值 return maxUnique == Integer.MIN_VALUE ? 0 : maxUnique; }
如果你的数组元素范围是已知的(比如都是非负整数且有明确上限),还可以用数组代替HashMap来进一步优化空间,但哈希表的方法通用性更强,适用于大多数场景。
对比你的原解法,这个版本把核心判断操作的复杂度从线性降到常数,真正实现了O(N)的时间效率,比你之前的解法高效得多。
内容的提问来源于stack exchange,提问作者Nesquik27




