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

[树/链表/图] 请教Hashmap 数量问题

全局:

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

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

x
各位大牛,我这里有一个小问题请教:刷题常常需要用到hashmap作为字典去存char出现的数目,我们都知道可以用一个int array去代替hashmap,每一个index对应一个unique char,我的问题是这个array多长比较合适?有人说128,因为ascii 表里有128个;有人说256,也就是unicode的数目。什么情况用unicode(比如只有english characters?)什么情况用unicode,用unicode的话应该用多长的array呢?
感谢大家!

评分

参与人数 2大米 +2 收起 理由
joanihh + 1 给你点个赞!
14417335 + 1

查看全部评分


上一篇:求leetcode上Amazon的题目清单
下一篇:LEETCODE FAANG 高频题汇总
推荐
zea7ot 2020-6-11 15:02:04 | 只看该作者
全局:
要具体看你需要建立的"词典"的大小。
比如说题目里面规定了只有小写字母,那么26的大小就足够了:
  1. int[] freq = new int[26];
复制代码
。可能有点啰嗦的是用
  1. ch - 'a'
复制代码
来定位,比如这句:
  1. ++freq[ch - 'a'];
复制代码
。与之对应的,还原成字符串的时候:
  1. freq[idx] + 'a'
复制代码
.
类似的,如果题目里面规定了只有大写字母情况,也可以用这样的办法解决。

但是,有时候题目里面有大写字母,也有小写字母,甚至还有特殊字符,但没有超出ASCII码的范畴,往往定义一个128大小的数组:
  1. int[] freq = new int[128];
复制代码
。但是就不需要+/- 'a'来进行定位了,直接
  1. freq[idx]
复制代码
就好。

有时候图省事,不想+/-'a',我会把第一种写成第二种。

基于数组的自加减会比基于Map自加减方便不少。freq[idx]的自加减操作是O(1),整个过一遍也不过是O(26/128) ~ O(1)。
但是如果"keys"太稀疏,也建议使用HashMap来建立"词典"。

评分

参与人数 3大米 +5 收起 理由
a_small_potato + 3 很有用的信息!
uilnauy + 1 赞一个
火锅烧烤麻辣烫 + 1 给你点个赞!

查看全部评分

回复

使用道具 举报

推荐
usr_opta 2020-6-11 12:22:16 | 只看该作者
全局:
没有必要纠结128还是256,不差那么几个byte。要真想知道到底几个,网上找一张ASCII表看看就知道了。
另外你对Unicode的理解有偏差,Unicode光基础字符就有0x0000~0xFFFF https://zh.wikipedia.org/wiki/Un ... 2%E6%98%A0%E5%B0%84

评分

参与人数 1大米 +1 收起 理由
火锅烧烤麻辣烫 + 1 感谢感谢。

查看全部评分

回复

使用道具 举报

全局:
取决于数据的key有多少个吧,而且只有key比较少的时候用array代替hashmap才有优势吧,不然array稀疏度太高了,用hash function可以使key尽量均匀分布, 而且一旦hashmap过饱和了,也会自动扩容的

评分

参与人数 1大米 +1 收起 理由
火锅烧烤麻辣烫 + 1 赞一个

查看全部评分

回复

使用道具 举报

🔗
 楼主| 火锅烧烤麻辣烫 2020-6-11 11:39:45 来自APP | 只看该作者
全局:
witcher_ciri 发表于 2020/06/11 10:55:50
取决于数据的key有多少个吧,而且只有key比较少的时候用array代替hashmap才有优势吧,不然array稀疏度太...
谢谢。如果确定key就是char,怎么能知道用128的ascii就够了而不需要unicode?
回复

使用道具 举报

🔗
witcher_ciri 2020-6-12 09:29:34 | 只看该作者
全局:
火锅烧烤麻辣烫 发表于 2020-6-10 22:39
谢谢。如果确定key就是char,怎么能知道用128的ascii就够了而不需要unicode?

取决于char这个数据类型占多少个bit吧,像c里面,每个char是8bit的话就是128种可能呗.Unicode每个字符是由多个byte组成的,不像一个char就是一个byte
回复

使用道具 举报

全局:
什么情况用?刷题的时候用。工作中这么用十有八九会崩。
回复

使用道具 举报

🔗
lyden999 2020-6-12 13:42:18 | 只看该作者
全局:
绝大多数情况遇到的char也就是word char(i.e., [a-z_A-Z0-9])和white space (\s)还有一切punctuation,很少涉及到unicode里面其他的字符的,最常见的就是统计26个字母,不放心就用256个,反正多出来也浪费不了多少空间但是可以防止数组越界

另外上面有人提到不同语言char类型的大小不一样,C语言就是一个byte(对应ascii的128个字符),java的char是2个byte,因为用的某种unicode
回复

使用道具 举报

🔗
zea7ot 2020-6-17 15:08:14 | 只看该作者
全局:
本帖最后由 leon7777777 于 2020-6-17 15:10 编辑

原来的帖子不能修改了,补充区域也写不了多少字。我干脆再回一贴吧,顺便求大米。
int[] freq = new int[26/128] 这样建立"字典",会在String - 去重、寻找Word Pattern(比如KMP算法)类问题里广泛使用。除了可以记住各个字母的frequency、实现Character <-> Integer的快速转换之外,还可以在使用滑动窗口寻找Word Pattern的时候,快速标记一个Word已经全部读入或者读出(具体可以参考KMP算法)。
使用HashMap也有其优点,比如需要记录的不仅仅是frequency,而是一些List(s)或者Set(s): Map<Integer, Set<Integer>>..., Map<Integer, List<Character>>..., etc.相对来说,适用面更广泛一些。
需要注意的是,accesses by keys in a HashMap不是严格意义上的O(1),而是amortized(1)。这点也可以在LC上直接得到印证。同样的"字典",HashMap会比array(int[])的耗时多不少。如果数据量不大,差异更是夸张。
回复

使用道具 举报

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

本版积分规则

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