【问题标题】:Algorithm that balances the number of elements in a subinterval of an array?平衡数组子区间中元素数量的算法?
【发布时间】:2014-05-19 00:41:24
【问题描述】:

假设您有一个包含 4 种不同类型元素的数组。

1 1 2 3 1 2 2 3 3 4 4 1.

我想找到导致每个元素数量相等且元素总数最大的最长子区间。

在这种情况下,它会是

1 1 2 3 1 2 2 3 3

因为这会导致 3 个二、三个三和三个一。

我相信这是某种修改后的动态编程,或者需要前缀和的东西,但我不太确定。有人可以告诉我如何开始吗?

【问题讨论】:

  • 你修复左边界。然后你一个接一个地增加右边界,跟踪每个数字的出现次数(你甚至不需要前缀总和)。您可以通过使用哈希映射将元素与它们在区间中出现的频率以及额外的多组出现次数相关联来检查区间是否平衡。
  • 它维护关联元素 -> 区间内的出现次数。
  • 不,如果你的数字是无限的,你就不能使用数组(我不知道它们是否是)。但是,在这种情况下,您可以使用坐标压缩和数组,是的。不,你不能对每个元素使用计数,否则你不会得到 O(n^2)。您需要将计数保存在单独的数据结构中,以便检查其所有元素在 O(1) 中是否相等(例如,再次将多重集实现为哈希表)
  • 正如我所说,你需要一个 second 数据结构。例如,保留出现次数的哈希图:1 -> 2, 3 -> 3, 4 -> 2。保留一个仅管理值集的附加多重集(在本例中为{2, 3, 2})。
  • 哈?这使您可以检查间隔是否平衡是 O(1)。只需检查多重集是否只包含一个不同的值。

标签: arrays algorithm dynamic-programming


【解决方案1】:
#!/usr/bin/env python

#The demo data
SET = [1,1,2,3,1,2,2,3,3,4,4,1]

#Function to map the counts of the values in the set
def map(x):
        ret = {}
        for v in x:
                if v not in ret.keys():
                        ret.update({v:0})
                ret[v] += 1
        return ret

#Function to check if all counts in the map are the same
def checkMap(x):
        val = None
        for k,v in x.items():
                if val != None and v != val:
                        return False
                else:
                        val=v
        return True

#Determine the initial counts
counts = map(SET)

#Now step back from end index to start
for ix in range(len(SET) - 1, 0, -1):
        val = SET[ix]
        counts[val] += -1
        if counts[val] == 0:
                del counts[val]
        if checkMap(counts):
                print "Condition Reached, Largest Subset is:",SET[0:ix]
                break

【讨论】:

  • 谁说最优子区间是地图的前缀?此外,这在复杂性方面也不是一个非常理想的解决方案。这是 O(n^2),但我们已经知道 OPs 问题的 O(n^2) 解决方案
  • 尝试A = [1,1,2,3,4,5,...,n+1] 并假设k=1 始终是checkMap 中循环中检查的最后一个数字(通常,即使假设散列良好,它也应该是被检查的第k/2 个数字如果x 中有 k 个数字)。因此checkMap 在前缀大小上是线性的。所以总运行时间是 O(1 + 2 + ... + n) = O(n^2)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-19
  • 2016-07-28
  • 1970-01-01
相关资源
最近更新 更多