187.重复的DNA序列 - 力扣

DNA序列 由一系列核苷酸组成,缩写为 'A', 'C', 'G' 和 'T'.。

  • 例如,"ACGAATTCCG" 是一个 DNA序列 。

在研究 DNA 时,识别 DNA 中的重复序列非常有用。

给定一个表示 DNA序列 的字符串 s ,返回所有在 DNA 分子中出现不止一次的 长度为 10 的序列(子字符串)。你可以按 任意顺序 返回答案。

        在说这题之前先来了解一下滑动窗口算法吧。滑动窗口有两种类型,类型一是固定窗口的,例如这题;另一种类型是窗口是可变的,也就是不固定的,例如力扣上的第3题无字符的最长子串。对可变窗口的滑动窗口感兴趣的话,可以去写一写。滑动窗口可以用来结束序列或数组等问题。

        滑动窗口又跟双指针有关系,可是设置左右指针,左右指针中间的距离就成为窗口。左右指针的位置可以根据所需来定义。

  • 当左右指针都为0时,遍历该序列或数组等,先移动右指针。当满足条件时,记录当前答案并移动左指针,移动之后发现条件已经不满足了,就又移动右指针。反复循环,直到右指针到达该序列或数组等的末尾,等到答案。
  • 左指针为0,右指针为左指针+窗口值。遍历该序列或数组,满足条件就记录答案,左指针++;若不满足答案,则不记录答案,继续左指针++,直到右指针到达该序列或数组的末尾。

这题我是使用滑动窗口的第二种方式方法来实现的。 

优化代码前:

 利用List存放结果,Map<String,int>来存放截取该序列所得的子序列和出现的次数。把左指针设置为0,右指针为10(窗口值),遍历序列得出答案。

List<String> list = new ArrayList<>();
Map<String,Integer> map =new HashMap<>();
int left=0,right=10;
int length = s.length();
while (right <= length){
    String sub = s.substring(left, right);
    if (map.containsKey(sub)){
        map.put(s.substring(left++,right++),map.get(sub)+1);
    }else {
        map.put(s.substring(left++,right++),1);
    }
}
for (String s1 : map.keySet()) {
    if (map.get(s1) >1){
        list.add(s1);
    }
}
return list;

优化代码后:

利用List存放结果,Map<String,int>来存放截取该序列所得的子序列和出现的次数。把左指针设置为0,右指针为左指针+10(窗口值),遍历序列得出答案。

List<String> list = new ArrayList<>();
Map<String,Integer> map =new HashMap<>();
int left=0,L=10;
while (L+left <= s.length()){
     String sub = s.substring(left,left+L);
     map.put(sub,map.getOrDefault(sub, 0) + 1);
     left++;
     if (map.get(sub).equals(2)){
          list.add(sub);
     }
}
return list;

可以看的出来优化后的代码更加简洁、优雅。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值