查看: 2007| 回复: 19
跳转到指定楼层
上一主题 下一主题
收起左侧

[学Java/C#] 求问187题Rolling Hash参数是4 ?????

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
本帖最后由 zurich.hill 于 2020-7-20 23:23 编辑

这题是 187. Repeated DNA Sequences

第12行,/** rolling hash 的参数 */, 这里为何 int a = 4?   有几个同学说,用质数避免相撞,因为有4个编码,或者因为要用4进制,之类的。

我测试过,3不行,4-8都可以,9之后就不行了。这到底是为什么,谁能给个解释吗?  

感谢,并且不要脸的要一个米~

  1. ********************************************************************************
  2. class Solution {

  3.         public List<String> findRepeatedDnaSequences(String s) {

  4.                 int L = 10, n = s.length();

  5.                 /** 边界条件 */
  6.                 if (n <= L) return new ArrayList();

  7.                 /** rolling hash 的参数 */
  8.                 int a = 4;
  9.                 int aL = (int)Math.pow(a, L);

  10.                 /** 把输入转成 int */
  11.                 Map<Character, Integer> toInt = new HashMap();

  12.                 toInt.put('A', 0);
  13.                 toInt.put('C', 1);
  14.                 toInt.put('G', 2);
  15.                 toInt.put('T', 3);

  16.                 int[] nums = new int[n];

  17.                 for(int i = 0; i < n; ++i) nums = toInt.get(s.charAt(i));

  18.                 int h = 0;  // --> hash 的存放值
  19.                 Set<Integer> seen = new HashSet();   // --> 检测工具
  20.                 Set<String> output = new HashSet();  // --> 结果容器

  21.                 /** 遍历input */
  22.                 for (int start = 0; start < n - L + 1; ++start) {

  23.                     /**  计算 hash of the current sequence in O(1) time */
  24.                     if (start != 0) {
  25.                          h = h * a - nums[start - 1] * aL + nums[start + L - 1];
  26.                     }

  27.                     /**  计算 hash of the first sequence in O(L) time */
  28.                     if (start == 0) {
  29.                          for(int i = 0; i < L; ++i) h = h * a + nums;
  30.                     }

  31.                     /** update output and hashset of seen sequences */
  32.                     if (seen.contains(h)) {
  33.                         output.add(s.substring(start, start + L));
  34.                     }

  35.                     seen.add(h);
  36.                 }

  37.                 return new ArrayList<String>(output);
  38.         }
  39. }
  40. ********************************************************************************
复制代码


上一篇:不懂就问,请问ds/mle刷算法要到什么程度?
下一篇:Leetcode刷题笔记#3
全局:
zurich.hill 发表于 2020-7-22 11:55
谢谢大神,但没看懂你的意思啊~

2147483647                                                       ...

java 里面int是32bit的,正数最大只能储存2^31-1, 也就是2147483647。 往这个上面+1就超过了它能储存的区间,就是overflow,所以变成了-2^31。这是不会报错的,但是会让你的运行结果出现错误。

你的基础知识比较欠缺,我建议在刷leetcode题目之前先补习一下基本数据类型和数据结构                                                                                                                  
回复

使用道具 举报

推荐
 楼主| zurich.hill 2020-7-22 11:55:11 | 只看该作者
全局:
浴火羽腾YZCR 发表于 2020-7-22 11:23
你为什么认为overflow 会报错呢? Java overflow 会wrap around,不会报错
        int a = (int)(Math. ...

谢谢大神,但没看懂你的意思啊~

2147483647                                                                                                                                                            
-2147483648  

啥意思啊  哈哈
回复

使用道具 举报

推荐
Dustinlo 2020-7-22 15:22:13 | 只看该作者
全局:
zurich.hill 发表于 2020-7-22 11:55
谢谢大神,但没看懂你的意思啊~

2147483647                                                       ...

加個mod可以解決約你的問題 但是code要改

(你給的code也還不能運行,所以應該沒差)

所以你可以選擇糾結或者move on lol

投入不會overflow的python也是個選擇

只是bit manipulation有時候要加mask有點煩
回复

使用道具 举报

全局:
9的话就会产生integer overflow
回复

使用道具 举报

🔗
 楼主| zurich.hill 2020-7-21 11:14:14 | 只看该作者
全局:
浴火羽腾YZCR 发表于 2020-7-21 11:11
9的话就会产生integer overflow

为什么呢?  我运行过,不是报overflow的错。奇怪~
回复

使用道具 举报

🔗
conghao2016 2020-7-21 17:11:48 | 只看该作者
全局:
zurich.hill 发表于 2020-7-21 11:14
为什么呢?  我运行过,不是报overflow的错。奇怪~

老哥。。那个解法你仔细看看 是math。pow,L=10, 9^10很大的一个数字- -其实就是差不多一个质数就行,太小了hash不开,这个方法的核心在于自己搞一个hash,方法是基于rabin-karp算法,所以你试验的45678都行实际上最终都要乘以10次,相当于hash
回复

使用道具 举报

🔗
conghao2016 2020-7-21 17:13:30 | 只看该作者
全局:
zurich.hill 发表于 2020-7-21 11:14
为什么呢?  我运行过,不是报overflow的错。奇怪~

至于不是interger overflow,因为 正整数极大以后你可以试试Integermaxvalue+1会得出啥- -....会变成integer.minvalue...虽然不会报错但因为hash function失败了,所以不会得到正确结果 如果你把int啥的都换成long 那么a取10以上就好使了
回复

使用道具 举报

全局:
conghao2016 发表于 2020-7-21 17:11
老哥。。那个解法你仔细看看 是math。pow,L=10, 9^10很大的一个数字- -其实就是差不多一个质数就行,太小 ...

我理解不需要是质数。可能正规的hash function需要质数,但是这个算法用的是input space的大小。因为DNA只有4个字母所以选4就够了。当然我们可以假设input可以是全部26个字母,而我们现在处理的这个数据恰好只用了前四个,但是以后可能遇到剩下的,那么就得用26
回复

使用道具 举报

🔗
 楼主| zurich.hill 2020-7-22 02:36:57 | 只看该作者
全局:
conghao2016 发表于 2020-7-21 17:11
老哥。。那个解法你仔细看看 是math。pow,L=10, 9^10很大的一个数字- -其实就是差不多一个质数就行,太小 ...

我知道。但我把参数调成11,12,13,并没有报错益处的问题。是的我知道rabin-karp

你说参数调成3,hash不开,能具体解释一下怎么hash不开呢?
回复

使用道具 举报

🔗
 楼主| zurich.hill 2020-7-22 02:37:29 | 只看该作者
全局:
浴火羽腾YZCR 发表于 2020-7-21 11:11
9的话就会产生integer overflow

你怎么知道呢?  我在lc上没有看到overflow的报错,反而是结果不一样的报错

你可以试一下
回复

使用道具 举报

🔗
 楼主| zurich.hill 2020-7-22 02:38:32 | 只看该作者
全局:
浴火羽腾YZCR 发表于 2020-7-21 23:56
我理解不需要是质数。可能正规的hash function需要质数,但是这个算法用的是input space的大小。因为DNA ...

好的,我知道你这个说话,但是谁能证明下,4就一定要4,26的话就要用26呢?  

据说是bit相关?

00
01
10
11
回复

使用道具 举报

🔗
conghao2016 2020-7-22 05:21:19 | 只看该作者
全局:
zurich.hill 发表于 2020-7-22 02:38
好的,我知道你这个说话,但是谁能证明下,4就一定要4,26的话就要用26呢?  

据说是bit相关?

不一定- -这个是算法基础的知识- -rabin karp算法你必须得搞懂这个算法才行
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表