如何解决给定二进制字符串“ 10110”查找所有设置位数> = n的子字符串的计数
我们可以用蛮力解决这个问题,获取所有可能的子字符串并检查设置的位数是否大于n。
我被要求在o(n)中解决这个问题。我在o(n)中找不到任何可以解决这个问题的答案。
是否有可能在0(n)中获得二进制字符串的所有可能子字符串?
解决方法
答案已更改(在问题陈述中注意到 >=
。
制作两个索引-left
和right
。
我们要考虑从位置left
开始至少包含k
ones
的子字符串。
首先移动right
,直到位数达到k
。
现在,我们有了一些“好”子字符串,它们从left
开始并在right
之后的任何位置结束,因此我们可以在结果中添加len(s) - right + 1
。
将left
递增1,直到下一个one
。
重复移动right
,依此类推。算法是线性的。
Python示例:
s = '0010110010'
#s = '110010110010'
k = 2
left = 0
right = 0
res = 0
cnt = 0
while right < len(s):
while (right < len(s)) and (cnt < k):
if s[right] == "1":
cnt += 1
right +=1
while (left <= right) and (cnt >= k):
addend = len(s) + 1 - right
res += addend
print(left,right,addend,res) #intermediate debug output
if s[left] == "1":
cnt -= 1
left +=1
print(res)
0 5 6 6
1 5 6 12
2 5 6 18
3 6 5 23
4 6 5 28
5 9 2 30
30
,
让N =计数为“ 1” 并让M =计数为'0'
int sum = 0 ;
for( int i = n ; i <= N; i++ ) sum += C(N,i) ;
sum *= 1<<M ;
总和就是你的答案。
,一种有用的方法是问自己,有多少个子字符串小于设置的{em> {em} 。
如果您可以回答这个问题,那么原始问题的答案就在附近。
为什么修改后的问题更容易掌握?因为当您有一个设置为n
位的S
子字符串时,包含n
的 any 子字符串将至少具有S
位已设置,因此您无需检查任何一个。
因此,假设您有一个子字符串。如果设置的位数少于n
,则可以对其进行扩展以容纳更多的位数。如果它设置了n
或更多位,则无法增长,必须缩小它。
假设您从最左边的空子字符串开始,开始索引为0,结束索引为0,长度为0。(当然,这是一个半开间隔)。它没有设置位,因此您可以扩展它。它可以增长的唯一方向是通过增加其最终索引向右。它不断增长,不断增长,直到吃掉n
1位;现在它必须缩小。应该如何缩小?显然,将其向相反方向缩小(减小其最终索引)将无济于事。您将到达刚刚检查过的子字符串!因此,您应该通过增加起始索引从左侧开始缩小它。因此它会不断收缩,直到它从后端排出1位为止。现在它具有n
个1位,并且可以再次增长。
不难证明您会枚举用这种方式设置的少于n-1
位的所有字符串。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。