当前位置: 首页 > article >正文

力扣labuladong一刷day21天滑动哈希算法共2题

力扣labuladong一刷day21天滑动哈希算法共2题

文章目录

      • 力扣labuladong一刷day21天滑动哈希算法共2题
      • 一、187. 重复的DNA序列
      • 二、28. 找出字符串中第一个匹配项的下标

一、187. 重复的DNA序列

题目链接:https://leetcode.cn/problems/repeated-dna-sequences/description/
思路:字符串序列里找重复出现的子串就是子串匹配问题,正常的思路是截取所有长为L的子串,看set里是否重复,可是截取的过程是O(n)每个都截取就成了O(x*n)。采用另外一种思路,也是滑动窗口,只不过把滑动窗口中的字符串映射成数字,这种映射的方式就是right右移尾部加数,left右移头部减数,复杂度是O(1)。这样只需要比较set中的映射值即可。

class Solution {
    public List<String> findRepeatedDnaSequences(String s) {
        Set<String> list = new HashSet<>();
        Set<Integer> set = new HashSet<>();
        int[] nums = new int[s.length()];
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == 'A') {
                nums[i] = 0;
            } else if (c == 'C') {
                nums[i] = 1;
            } else if (c == 'G') {
                nums[i] = 2;
            }else {
                nums[i] = 3;
            }
        }
        int hashcode  = 0, left = 0, right = 0, r = 4;
        int rl = (int) Math.pow(r,9);
        while (right < nums.length) {
            hashcode = hashcode * r + nums[right];
            right++;
            if (right - left == 10) {
                if (set.contains(hashcode)) {
                    list.add(s.substring(left, right));
                }else {
                    set.add(hashcode);
                }
                hashcode = hashcode - nums[left] * rl;
                left++;
            }
        }
        return new ArrayList<>(list);
    }
}

二、28. 找出字符串中第一个匹配项的下标

题目链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/
思路:滑动窗口使用needmap和windowmap要求需要匹配的是子串的排列,如果不是排列是无法区分ab与ba的。本题是完全匹配就只能用滑动哈希算法了。

选择一个较大的素数Q,这样会减少哈希碰撞。

class Solution {
   public int strStr(String haystack, String needle) {
        long Q = 1658598167, L = needle.length(), R = 256;
        long hashCode = 0, patCode = 0;
        long RL = 1;
        for (int i = 0; i < L - 1; i++) {
            RL = (RL*R) % Q;
        }
        for (int i = 0; i < L; i++) {
            patCode = (patCode * R+ needle.charAt(i)) % Q;
        }
        int left = 0, right = 0;
        while (right < haystack.length()) {
            hashCode = ((hashCode * R) % Q + haystack.charAt(right)) % Q;
            right++;
            if (right - left == L) {
                if (hashCode == patCode) {
                    if (needle.equals(haystack.substring(left, right))) return left;
                }
                hashCode = (hashCode - (haystack.charAt(left)*RL) % Q + Q) % Q;
                left++;
            }
        }
        return -1;
    }
}

http://www.kler.cn/news/149160.html

相关文章:

  • sqli-labs靶场详解(less29-less31)
  • 【工具】Zotero|使用Zotero向Word中插入引用文献(2023年)
  • Labview Lite Note
  • 关于分页的问题SQL_CALC_FOUND_ROWS
  • 每日一题:LeetCode-202.面试题 08.06. 汉诺塔问题
  • 11.28C++
  • Linux环境安装Java,Tomcat,Mysql,
  • 腾讯云轻量服务器通过Docker搭建外网可访问连接的redis5.x集群
  • CCFCSP试题编号:202109-2试题名称:非零段划分
  • leetcode每日一题35
  • Web学习笔记
  • 面试必须要知道的MySQL知识--索引
  • AntDB数据库:从海量数据处理,到5G计费商用核心
  • 使用vue-admin-template时,需要注意的问题,包括一定要去除mock.js注释
  • 0005Java程序设计-ssm基于微信小程序的校园求职系统
  • Java后端开发——MVC商品管理程序
  • Java Web基础教程
  • 第二证券:燃料电池产业进入发展快车道 多家公司披露布局进展
  • 【FGPA】Verilog:JK 触发器 | D 触发器 | T 触发器 | D 触发器的实现
  • 【MATLAB】RLMD分解+FFT+HHT组合算法
  • NOI / 1.7编程基础之字符串 30:字符环 c语言 两次遍历解决循环
  • 11.27二叉查找树,遍历二叉树,层序(判断是不是完全二叉树),根据遍历序列重构二叉树,递归输入建树(树的定义,结构体细节,typedef)
  • Spring Boot进行单元测试,一个思路解决重启低效难题!
  • Docker compose启动服务遇到的问题
  • el-tabel实现拖拽排序
  • 绩效考核的基础及基本内容
  • NOI / 1.8编程基础之多维数组 提问24:蛇形填充数组 c语言
  • 进程和线程的关系
  • 力扣106. 从中序与后序遍历序列构造二叉树
  • linux(2)之buildroot使用手册