Python 求0和1个数相等的相邻子阵列的最大长度的DP解
问题就在这里 事实上,我为这个问题想出了一个DP解决方案。 然而,它不会通过一个测试用例 有什么想法吗 DP[i][j]==1表示从子字符串[i]到子字符串[j]有效 把问题分成几个小部分 DP[i][j]==1Python 求0和1个数相等的相邻子阵列的最大长度的DP解,python,algorithm,dynamic-programming,Python,Algorithm,Dynamic Programming,问题就在这里 事实上,我为这个问题想出了一个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 ``` 当
- 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
```
当前最大长度=0
如果不是nums:
返回电流最大值
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
```
这里是一个反例
[1,1,0,0,0,0,1,1]
。您解决的问题是,它需要一个由大小为n-1或n-2的较小有效列表组成的列表。在这个反例中,它是两个长度为4
或n-2
的列表剧透警报——你可以通过使用其他dp技术来解决这个问题,基本上对于每个i,j,你可以在固定的时间内找到它们之间的1和0的数量,只需存储从列表开始到每个索引i的1的数量
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))
定义函数(nums):
磁道,has=0,{0:-1}
长度=长度(nums);
ress_max=0;
对于范围内的i(0,长度):
轨迹+=(如果nums[i]==1,则为1,否则为-1)
如果轨道不在,则:
has[轨道]=i
elif ress_max,因为二进制字符串的给定长度可能最多为
50000
。因此,运行O(n*n)
算法可能会导致时间限制超过
。我想建议您在O(n)
时间和空间复杂性中解决它。这个想法是:
- 如果我们取任何有效的连续子序列,并将
处理为0
,则总和应始终为-1
0
- 如果我们跟踪前缀和,那么我们可以在
到L
的范围内得到零和,如果前缀和达到R
和前缀和达到L-1
相等R
- 因为我们在寻找最大长度,所以我们将始终将新找到的求和的索引作为第一个索引,并将其放入
,值作为当前索引,并且对于特定的求和,该索引将永远保持不变哈希映射
- 每次我们计算累积总和时,我们都会查看它是否以前发生过。如果它以前出现过,我们将计算长度并尝试最大化,否则它将是第一个,并且将永远保留在哈希映射中,值作为当前索引
- 注意:要计算纯前缀,我们必须将求和
已在映射中,并与值0
配对作为索引-1
C++
中的示例代码如下:
int findMaxLength(vector<int>& nums) {
unordered_map<int,int>lastIndex;
lastIndex[0] = -1;
int cumulativeSum = 0;
int maxLen = 0;
for (int i = 0; i < nums.size(); ++i) {
cumulativeSum += (nums[i] == 0 ? -1 : 1);
if (lastIndex.find(cumulativeSum) != lastIndex.end()) {
maxLen = max(maxLen, i - lastIndex[cumulativeSum]);
} else {
lastIndex[cumulativeSum] = i;
}
}
return maxLen;
}
int findMaxLength(向量和nums){
无序映射索引;
lastIndex[0]=-1;
int-cumulativeSum=0;
int maxLen=0;
对于(int i=0;i
你指出了根本原因。我错过了这个案子。非常感谢!