最长的连续子序列,使得零的数量的两倍小于等于三的数量的一个

时间:2013-09-24 03:57:37

标签: c++ algorithm

我试图从黑客级别解决这个问题我尝试了粗暴的解决方案但它似乎没有工作。有人可以有效地解决这个问题。 https://www.hackerrank.com/contests/sep13/challenges/sherlock-puzzle

给定一个包含'0'和'1'以及整数K的二进制字符串(S), 找到(S * K)的最长连续子序列的长度(L),使得零的数量的两倍&lt; =该序列中的1的数量(2 *#0 <= 3 *#1s)的三倍。

S * K定义如下:S * 1 = S. S * K = S + S *(K-1)

输入格式 第一行(也是唯一一行)包含整数K和由单个空格分隔的二进制字符串S.

约束 1&lt; = | S | &lt; = 1,000,000 1&lt; = K <= 1,000,000

输出格式 单个整数L - 测试用例的答案

2 个答案:

答案 0 :(得分:0)

这里有一个提示:

让我们首先假设K = 1并且S看起来像(使用点0表示):

..1...11...11.....111111....111....
      e    f      b  a c    d

关键是要注意,如果最长的可接受序列包含1,它也将包含任何相邻序列。例如,如果最长序列在 a 处包含1,则它还将包含 b c (包括)之间的所有序列。

所以你只需要分析那些块的序列。

主要问题是:如果你从某个区块开始,你可以进入下一个区块吗?例如,如果您从 e 开始,则可以将其转到 f 的块,但不能转到 b 。如果您从 b 开始,您可以在 d 等处进入该块。

然后概括分析K> 1。

答案 1 :(得分:0)

蛮力显然不会起作用,因为它是O((n * k) ** 2)。我将在这个答案中使用python样式列表推导。你需要一个数组t = [3 if el == "1" else - 2 for el in S]。现在,如果您使用p[i] = t[0] + ... + t[i]数组,您可以看到在k == 1情况下您基本上正在寻找一对(i,j),i&lt; j使p[j] - (p[i - 1] if i != 0 else 0) >= 0为真,j - i为最大 这些对。现在,对于每个i in 0..n-1,您必须找到它的j对,以便上面是最大的。这可以在O(log n)中针对特定i完成,因此这为k == 1案例提供了O(n log n)解决方案。对于一般情况,这可以扩展到O(n log n)解决方案(有一个技巧可以找到可以覆盖的最大块)。此问题还有一个O(n)解决方案,但您需要进一步检查p序列。我建议不要用脚本语言编写解决方案。即使O(n)解决方案在python中超时......