DP解决方案,以找到数量等于0和1的连续子数组的最大长度

时间:2018-12-16 19:09:41

标签: python algorithm dynamic-programming

问题来自这里https://leetcode.com/problems/contiguous-array/

实际上,我针对此问题提出了DP解决方案。 但是,它不会通过一个测试用例。

有什么想法吗?

DP [i] [j] == 1表示从子字符串[i]到子字符串[j]有效

将问题分成较小的

DP [i] [j] == 1

- if DP[i+2][j]==1 and DP[i][i+1]==1
- else if DP[i][j-2]==1 and DP[j-1][j]==1
- else if num[i],num[j] == set([0,1]) and DP[i+1][j-1]==1

```         current_max_len = 0         如果不是数字:             返回current_max_len

    dp = [] * len(nums)
    for _ in range(len(nums)):
        dp.append([None] * len(nums))

    for thisLen in range(2, len(nums)+1, 2):
        for i in range(len(nums)):
            last_index = i + thisLen -1
            if i + thisLen > len(nums):
                continue

            if thisLen==2:
                if set(nums[i:i+2]) == set([0, 1]):
                    dp[i][last_index] = 1
            elif dp[i][last_index-2] and dp[last_index-1][last_index]:
                dp[i][last_index] = 1
            elif dp[i][i + 1] and dp[i + 2][last_index]:
                dp[i][last_index] = 1
            elif dp[i + 1][last_index-1] and set([nums[i], nums[last_index]]) == set([0, 1]):
                dp[i][last_index] = 1
            else:
                dp[i][last_index] = 0
            if dp[i][last_index] == 1:
                current_max_len = max(current_max_len, thisLen)

    return current_max_len

```

enter image description here

3 个答案:

答案 0 :(得分:1)

这是一个反例[1, 1, 0, 0, 0, 0, 1, 1]。您的解决方案存在的问题是,它需要一个列表由大小为n-1或n-2的较小有效列表组成,在此反例中,它是两个长度为4n-2的列表。 -SPOILER ALERT-您可以通过基本上对每个i,j使用其他dp技术来解决该问题,您可以在恒定时间内找到它们之间的一和零的数量,而只需从开始就存储一的数量即可。列出每个索引i

答案 1 :(得分:0)

这是python代码

def func( nums):       
    track,has=0,{0:-1}
    length=len(nums);
    ress_max=0;

    for i in range(0,length):
        track += (1 if nums[i]==1 else -1)
        if  track not in has:
            has[track]=i
        elif ress_max <i-has[track]:
            ress_max = i-has[track]
    return ress_max

l = list(map(int,input().strip().split()))
print(func(l))

答案 2 :(得分:0)

由于给定的二进制字符串长度最多为50000。因此,运行O(n * n)算法可能会导致time limit exceed。我建议您解决O(n)的时间和空间复杂性问题。这个想法是:

  • 如果我们采用任何有效的连续子序列并执行将0视为-1的数字求和,则总和应始终为zero
  • 如果我们跟踪前缀求和,那么我们可以得到LR范围内的零求和,如果前缀求和为L - 1,前缀求和为{{1} }相等。
  • 由于我们正在寻找最大长度,因此我们将始终将新发现的总和的索引作为第一个索引,并将其放入R中,并将其值作为当前索引,并且对于该特定总和将永久存在。
  • li>
  • 每次我们计算累积总和时,我们都会查看它是否有任何先前的出现。如果它以前发生过,我们将计算长度并尝试将其最大化,否则它将是第一个,并且将永久保留在哈希映射中,并将值作为当前索引。
  • 注意:要计算纯前缀,我们必须将求和hash map已经在映射中,并与值0配对作为索引。

-1中的示例代码如下:

C++