【问题标题】:Finding the minimum unique number in an array查找数组中的最小唯一数
【发布时间】:2012-08-14 01:54:18
【问题描述】:

数组中的最小唯一数定义为 min{v|v occurs only once in the array} 例如,{1, 4, 1, 2, 3} 的最小唯一数为 2。 有没有比排序更好的方法?

【问题讨论】:

  • “更好”的意思是“更低的时间复杂度”?
  • @VaughnCato:是的,我想知道我们是否能比 O(nlogn) 做得更好。
  • 您的值的范围是受限还是受限?如果它们在受限范围内积分,我相信 O(N) 是可能的。
  • @walrii:元素可以是任何整数。但是,请随时展示您的解决方案,其中包含您上面提到的限制。

标签: algorithm


【解决方案1】:

我相信这在时间和空间上都是一个 O(N) 的解决方案:

HashSet seenOnce;     // sufficiently large that access is O(1)
HashSet seenMultiple; // sufficiently large that access is O(1)

for each in input // O(N)
    if item in seenMultiple
        next
    if item in seenOnce
        remove item from seenOnce
        add to item seenMultiple
    else
        add to item seeOnce

smallest = SENTINEL
for each in seenOnce // worst case, O(N)
    if item < smallest
        smallest = item

如果您的整数值范围有限,您可以将 HashSets 替换为按该值索引的 BitArrays。

【讨论】:

  • 这一切都很好,先生,但是我在哪里可以找到您所说的这个神奇的 O(1) 随机访问哈希函数?据我(和世界其他地方)所知,散列函数的“最佳”随机访问时间是 O(logn)。
  • 除非我遗漏了什么,否则不需要随机访问。第一次遍历input (O(N)) 并在哈希集上进行查找、插入和删除,每个 O(1)。总计:O(N)。所写的第二遍当前循环遍历seenOnce,但这很容易解决:只需再次循环遍历input (O(N)),测试seenOnce 中的成员资格(O(1)),如果存在则追加它到一个新的seenOnceList (O(1)),总共 O(N)。最后扫描最小值,O(N)。净 O(N),不是吗?
  • @ElKamina - 您将树与哈希混淆了。请参阅en.wikipedia.org/wiki/Big_O_notation#Orders_of_common_functions 并查看 O(1) 下的列表。使用大表和适当的散列函数,冲突是微不足道的。
  • @DSM - 我对 seenOnce 的循环就是您所说的“扫描最小值”。您添加的额外循环的目的是什么?
  • @DSM - 数组优化的优点是哈希函数 = I() 并且不需要冲突处理。没有 Big-O 优势,这是理所当然的,但更简单、更快。
【解决方案2】:

您不需要进行完全排序。执行冒泡排序内循环,直到在一端获得明显的最小值。在最好的情况下,这将具有时间复杂度 O(k * n),其中 k = 非不同最小值的数量。然而,最坏情况的复杂度是 O(n*n)。因此,当 k 的期望值时,这可能是有效的

我认为这将是可能的最小时间复杂度,除非您可以使任何 O(n * logn) 排序算法适应上述任务。

【讨论】:

    【解决方案3】:

    使用字典的 Python 版本。
    时间复杂度O(n)和空间复杂度O(n):

    from collections import defaultdict
    d=defaultdict(int)
    for _ in range(int(input())):
        ele=int(input())
        d[ele]+=1
    m=9999999
    for i in d:
        if d[i]==1 and i<m:
            m=i
    print(m if m!= 9999999 else -1)
    

    请告诉我是否有更好的方法。

    【讨论】:

      猜你喜欢
      • 2019-02-13
      • 2012-06-30
      • 1970-01-01
      • 2013-04-24
      • 1970-01-01
      • 2015-12-08
      • 2018-09-24
      相关资源
      最近更新 更多