Algorithm 查找包含多达0次O(n)的1的最长子序列
我在一次面试中遇到了一个问题,我找不到最佳解决方案(这真是令人沮丧,哈哈) 所以你有一个1和0的n列表。 110000110101110.. 目标是提取包含1到0的最长子序列。 例如,这里是“110000110101”或“10000101011”或“000011101110” 我对O(n^2)有一个想法,只是从头到尾扫描所有的可能性,但显然有一种方法可以在O(n)中实现。 有什么想法吗Algorithm 查找包含多达0次O(n)的1的最长子序列,algorithm,sorting,count,sequence,Algorithm,Sorting,Count,Sequence,我在一次面试中遇到了一个问题,我找不到最佳解决方案(这真是令人沮丧,哈哈) 所以你有一个1和0的n列表。 110000110101110.. 目标是提取包含1到0的最长子序列。 例如,这里是“110000110101”或“10000101011”或“000011101110” 我对O(n^2)有一个想法,只是从头到尾扫描所有的可能性,但显然有一种方法可以在O(n)中实现。 有什么想法吗 非常感谢 考虑一下'10110': 创建一个变量S。创建数组A=[0] 从第一个数字开始迭代,如果注意到1,则
非常感谢 考虑一下
'10110'
:
S
。创建数组A=[0]
李>
S
附加到A
- 对于我们的示例序列,
将是:A
[0,1,0,1,2,1]
只是一个数组,它存储索引前面的1和0之间的差值。序列必须在1s和0s之间具有相同差异的位置开始和结束。所以现在我们的任务是在A
中找到相同数字之间的最长距离李>A
First
和Last
A
并将A
中每个数字的第一次出现位置保存在字典first
中A
(从末尾开始),并在字典last
中保存每个数字在A
中最后一次出现的位置
- 因此,对于我们的示例,首先是
,最后是{0:0,1:1,2:4}
{0:2,1:5,2:4}
max_key
)键,该键的First
和Last
中的对应值之间的差值最大。此最大差异是子序列的长度。子序列从第一个[max\u key]
开始,到最后一个[max\u key]
结束def find_子序列(seq):
S=0
A=[0]
对于下文中的e:
如果e=='1':
S+=1
其他:
S-=1
A.追加(S)
第一={}
最后={}
对于位置,枚举(A)中的e:
如果e不在第一位:
第一[e]=pos
对于位置,枚举中的e(反向(A)):
如果e不在最后:
最后[e]=长度(顺序)-位置
最大差值=0
最大密钥=无
对于“先输入”选项:
差异=最后一个[键]-第一个[键]
如果差异>最大差异:
最大差值=差值
最大键=键
如果max_key为None:
返回“”
返回顺序[第一个[最大键]:最后一个[最大键]]
查找顺序('10110')#给出'0110'
查找序列('1')#给出“”
它更加优化
额外的 这一问题与环境有关。其解决方案也基于从一开始就对元素求和:
def max_subarray(arr):
max_diff = total = min_total = start = tstart = end = 0
for pos, val in enumerate(arr, 1):
total += val
if min_total > total:
min_total = total
tstart = pos
if total - min_total > max_diff:
max_diff = total - min_total
end = pos
start = tstart
return max_diff, arr[start:end]
你是说最长的子串(即元素必须是连续的(相邻的))吗?通常,子序列允许间隙,例如,
[1,3]
是[1,2,3]
的子序列。子序列将是微不足道的。只需把整个序列去掉多余的0/1。@PiotrDabkowski:是的。这就是我问的原因(因为我认为OP的意思是子字符串
)。@J.F.Sebastian您的代码要好得多。我尽量让事情简单易懂:)顺便问一下,你写这段代码花了多长时间?git log
表示从最初提交(答案中的代码)到最终版本之间的时间超过了一个小时。我试着想出一种类似于单次通过、恒定内存算法的方法,但失败了。@J.F.Sebastian您成功地实现了单次通过。我认为不可能让它成为永久的记忆。在Kadane的算法中,您正在寻找值之间的最大差异。这里你要寻找的是相同值之间的最大距离。