Arrays 查找n个项目列表中是否有超过n/2个项目匹配。O(非直瞄(n))

Arrays 查找n个项目列表中是否有超过n/2个项目匹配。O(非直瞄(n)),arrays,algorithm,sorting,Arrays,Algorithm,Sorting,如何查找n个项目列表中的任何项目是否重复了n/2次以上。我希望它是快速的,所以它应该是O(nlogn),这里是关键:你只能检查项目是否相等,没有其他。我很难做得比O(n^2)更好如果你只能检查是否相等,那么这里有一个O(nlogn)解决方案: 按O(nlogn)时间对列表排序 让中间元素在排序数组中为m 现在,如果有一个元素重复次数超过n/2次,那么它只能是m。现在,您可以通过迭代中间索引的右侧和左侧来检查m的频率。如果找到的答案大于n/2,则该元素不存在 如果允许您做的不仅仅是检查是否相等

如何查找n个项目列表中的任何项目是否重复了n/2次以上。我希望它是快速的,所以它应该是O(nlogn),这里是关键:你只能检查项目是否相等,没有其他。我很难做得比O(n^2)

更好如果你只能检查是否相等,那么这里有一个
O(nlogn)
解决方案:

  • O(nlogn)
    时间对列表排序
  • 让中间元素在排序数组中为
    m
  • 现在,如果有一个元素重复次数超过
    n/2次,那么它只能是
    m
    。现在,您可以通过迭代中间索引的右侧和左侧来检查
    m
    的频率。如果找到的答案大于
    n/2
    ,则该元素不存在
如果允许您做的不仅仅是检查是否相等,您只需遍历数组并将元素的频率存储在HashMap中,然后检查频率是否超过
n/2
。这个解决方案在时间复杂度上是
O(n)

使用HashMap的O(n)解决方案的代码:

public int getDuplicated(List<Integer> a) {
    HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
    int n = a.size();
    for (int i = 0; i < a.size(); i++) {
        if (map.containsKey(a.get(i))) {
            // increasing the frequency
            map.put(a.get(i), map.get(a.get(i)) + 1);
        } else {
            map.put(a.get(i), 1);
        }
        if (map.get(a.get(i)) > n / 2) {
            // element found
            return a.get(i);
        }
    }
    // returning -1 if could not find the element
    return -1;
}
public int getDuplicated(列表a){
HashMap=newHashMap();
int n=a.size();
对于(int i=0;in/2){
//元素发现
返回a.get(i);
}
}
//如果找不到元素,则返回-1
返回-1;
}

使用,如建议副本的各种答案中所述。算法是O(n),这超出了您的规范。如果您不知道最常见的元素是多数元素,则需要进行第二次扫描,以计算通过boyer-moore算法找到的元素的出现次数。除非可以进行排序比较,否则无法排序;平等比较是不够的。另一方面,哈希映射不需要有序比较,但它需要操作项的能力,而不仅仅是比较。