题目:所有DNA都由一系列缩写为A,C,G,T的核苷酸组成。例如“ACGAATTCCG”。在研究DNA时,识别DNA中的重复序列有时会对研究非常有帮助。
编写一个函数来查找DNA分子中所有出现过超过一次的10个字母长的序列(子串)。
示例:
输入: s = “AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT”
输出:[“AAAAACCCCC”, “CCCCCAAAAA”]
分析:
这道题可以利用 滑动窗口 的思想来解决。固定一个大小为 10 的滑动窗口。从头开始,滑动整个字符串,直至字符串结尾。
滑动过程中记录每个出现的字符串以及其出现次数。这个操作用 map 可以很容易实现。以字符串 “AACCAACCAACCAAC” 为例,下面动画展示了滑动窗口的滑动过程。
实现代码:
func findRepeatedDnaSequences(s string) []string {
var mapper map[string]int //定义一个map用来存储滑动窗口中的字符串以及出现次数
mapper = make(map[string]int)
var i, j int
var tmp string
j = 0
//从滑动窗口右侧开始计起,右侧到达字符串末尾就停止滑动
for i = 10; i <= len(s); i++ {
tmp = s[j:i] //此方法可以很方便获取滑动窗口中的字符串
mapper[tmp]++
j++
}
var res []string
for k, v := range mapper {
if v >= 2 {
res = append(res, k)
}
}
return res
}
时间复杂度: 代码中只用了两个循环,第一次是遍历字符串,第二次是遍历map获取结果,都是线性时间,时间复杂度为 O(n) 。n为字符串长度。
空间复杂度: 代码中使用了哈希表map,所以空间复杂度为O(n).