【问题标题】:How do I find elements that are appear k-times in an unsorted list with O(1) space and O(n) time cost (with bounded element size) [closed]如何在具有 O(1) 空间和 O(n) 时间成本(有界元素大小)的未排序列表中找到出现 k 次的元素 [关闭]
【发布时间】:2012-02-14 22:44:29
【问题描述】:

这不是一个问题,而是一个汇总帖子。

所以问题是:如果要找到出现 n 次的元素,如何实现 O(1) 空间和 O(n) 时间复杂度操作一些值类型项(通常是整数或字符)列表,对列表进行排序还是查找所有唯一值?

一个小笔记。这仅适用于具有固定值范围的值类型对象(例如整数、字符等)。

更新

在排序或搜索出现 k 次、偶数次或唯一元素左右的元素时,有很多关于使用这种方法来实现 O(1) 空间和 O(n) 时间复杂度的问题.所以,请仔细阅读问题,尤其是第一句话。这是一个常见问题解答式的帖子,而不是一个问题。

另外,我知道答案,不需要一遍又一遍地发布。如果你觉得你可以添加一些有价值的东西 - 随意编辑问题和主题中最长的答案(注意这是我自己的答案),所以它成为一个社区维基。

相关问题:

  1. Finding the first non-repeated character of a string in O(n) using a boolean array?
  2. Find a single integer that occurs with even frequency in a given array of ints when all others occur odd with frequency
  3. Find if 2 strings are anagram in O(1) space and O(n) time
  4. Finding duplicates in O(n) time and O(1) space
  5. Find duplicates in an array
  6. O(n) algorithm to find out the element appearing more than n/2 times

【问题讨论】:

  • 我想我根本不明白这个问题。也许你应该把它分开。例如,您希望如何在 O(1) 空间中使用数组?你也不能在少于 O(n log n) 的时间内真正对数组进行排序(尽管 Radix 排序可以)。
  • @AdrianRatnapala,请参阅下面的答案。
  • @J0HN 如果您能添加一个示例以便我更好地理解这个问题,我将不胜感激?
  • 如果您希望您的答案是一个社区 wiki,您可以选中一个复选框。由于为时已晚,您可以将其标记并要求主持人。另外,听起来您正在尝试提出“规范问题”;如果是这样,请适当地改写。 meta.stackexchange.com/q/104877meta.stackexchange.com/q/63762meta.stackexchange.com/q/62695
  • 您在帖子中说了两次“这不是问题”。当五个人同意时不要感到惊讶,并且这样就结束了。

标签: algorithm list search sorting


【解决方案1】:

如果您使用有点偷偷摸摸的参数,即每个项目的唯一值的数量是固定的,那么您可以为每个 O(1) 空间的唯一值创建一个哈希映射。

现在你的问题的答案是微不足道的。只需遍历列表一次并累积哈希图中的出现次数。 O(n) 时间。

注意,要回答提出的问题,不需要排序

【讨论】:

    【解决方案2】:

    基本思想是 O(1) 空间复杂度实际上意味着内存消耗与数组的大小无关。

    因此,如果您正在操作的数组元素的范围有限(例如 -128..127),您可以分配一个长度为 max_value-min_value+1 的类似哈希的数组来跟踪每个值的出现次数(让我们暂时称它为计数数组)。

    使用这种方法,您只需扫描一次数组(因此 O(n) 时间复杂度),累积每个单独值的出现次数,最后您可以回答问题:

    1. 是否有出现奇数/偶数的元素?只有一个外观? 任意出现次数? (只需扫描计数数组)
    2. 初始数组中出现的唯一值是什么(在 count-array 中选择所有值 > 1 的键)
    3. 对数组进行排序(有点复杂,请参见下面的示例)

    最后,Python 上的一些代码示例

    import random, sys
    min_val = -5
    max_val = 5
    initial_array = [random.randint(min_val, max_val) for i in range (0,20)]
    count_array = {i:0 for i in range(min_val,max_val+1)}
    
    for elem in initial_array:
        count_array[elem]+=1
    
    #print initial_array
    
    #1. Find unique values
    unique_values = [item for item, count in count_array.iteritems() if count>0]
    #print unique_values
    
    #2. Find n-time-appearing values
    n=2
    n_times_appear = [item for item, count in count_array.iteritems() if count==n]
    #print n_times_appear
    
    #3. Find odd times appearing numbers
    odd_times_appear = [item for item, count in count_array.iteritems() if not count%2]
    #print odd_times_appear
    
    #4. Sort an array
    #We don't actually sort an array - we just reconstruct it.
    sorted_array = []
    for item,count in sorted(count_array.iteritems()):
        for i in range(0,count):
            sorted_array.append(item)
    
    #print sorted_array
    

    如果我错了,请随意添加其他语言实现并纠正我:)

    【讨论】:

    • 为了进一步扩展这一点,您可以进行二进制基数排序以对O(n) 中的任何固定宽度整数类型进行排序,然后扫描结果以执行您列出的任何其他操作。不过,这有点狡猾。
    • +1 以获得全面的答案。我唯一的批评是回答这个问题(查找出现 k 次的元素),不需要排序。
    【解决方案3】:

    由于输入大小是有界的,您可以简单地对输入运行Counting Sort 算法,然后找到您的结果。计数排序需要 O(n),并且在已排序的数组中找到特定出现时间的数组的特定元素是 O(n)。

    【讨论】:

    • O(n) 空间 - 不是 O(1)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 2014-10-16
    相关资源
    最近更新 更多