[编程题]病毒检测 Golang 数学解法 快手 2020

[编程题]病毒检测

最近在集中刷题,全部都写的话有点费时间,以后就只记录做得比较困难了。
这道题一入眼我首先想到的是双指针,但是仔细考虑一下发现左右指针轮流右移的思路行不通,如果一定要用双指针,需要右指针扫描完了回到起点再操作,这就和暴力法没什么区别了。
我想到另一种思路,创建一个数组pos[]记录每个1的位置。
我们结合一个例子来分析一下一般情形,针对如下的pos[]:

2 4 9 10 14 18

考虑第5个1,位置是14,假如k=3,第2个1的位置是4。
那么包含9,10,11这三个1的所有可能性可以表示为:
右侧滑动范围(14,18],左侧滑动范围((4,9],可能性有(18-14)*(9-4)=20种。
然后改变末位1的位置求得总共的可能性。

下附代码:

package main

import "fmt"

func main()  {
	var k,ans int
	var str string
	fmt.Scan(&k,&str)
	pos:= []int{-1}
	for i,v:=range(str){
		if v==49{	//"1"的ASCII码为49
			pos=append(pos, i)
		}
	}
	if k>=len(pos){
		fmt.Println(0)
		return
	}
	pos=append(pos, len(str))
	if k==0{
		for i:=k;i<len(pos)-1;i++{
			ans+=(pos[i+1]-pos[i]-1)*(pos[i+1]-pos[i])/2
		}
	}else {
		for i := k; i < len(pos)-1; i++ {
			ans += (pos[i+1] - pos[i]) * (pos[i-k+1] - pos[i-k])
		}
	}
	fmt.Println(ans)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值