You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何以近似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),具体步骤如下:

  1. 遍历数组一次,用HashMap记录每个元素的出现次数;
  2. 再次遍历数组(或直接遍历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

火山引擎 最新活动