力扣猜数字游戏及哈希表学习

 

 思路:对于公牛很简单,循环数组判断即可,母牛的话,首先想的是一个作为Set另外往里add,但是两者都有重复就对不上了,比如1122和2211,看了下解题思路,使用哈希表进行词频统计,低的那个即是母牛的答案(因为两次不匹配只会算一次)

    public static String getHint(String secret, String guess) {
        //在ASCII编码中, 0~9 的编码是 0x30(48D)~0x39(57D),
        // 所以当c在‘0'~'9'的范围中时,c - '0' 就相当于计算c的实际数值,
        // 例如 c 是 '1', 则 c - '0' = 1, 把字符值转为数字值了
        int length = guess.length();
        int[] seHash = new int[10];
        int[] guHash = new int[10];
        int a = 0; int b = 0;
        for(int i = 0 ; i < length; i++){
            int se = secret.charAt(i) - '0';
            int gu = guess.charAt(i) - '0';
            if(se == gu){
                a++;
            }else{
                seHash[se]++;
                guHash[gu]++;
            }
        }
        for(int i = 0 ; i < 10; i++){
            b += Math.min(seHash[i],guHash[i]);
        }
        return a+"A"+b+"B";
    }

哈希表学习

这道题的关键是活用哈希表,先重新复习了下什么是哈希表

哈希表也叫散列表,是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表

也就是说将存入的数据,根据某个函数进行计算,得出一个key,再通过key存放真正要存放的数据,就像数据的下标,根据下标访问效率会很快。

不过一般使用的HashMap存储的都是键值对,所以可以理解为通过键值对的键值算出一个数组下标,根据数组下标,将对应的entry存入,下次查找时,只需要根据entry的key通过同样的散列函数算出下标,获取的时候就非常的快。

哈希冲突

通过散列函数算出的下标如果出现重复,那就称之为哈希冲突,处理方法一个是开放寻址法,一个是拉链法

开放寻址法:

简单来说,当算出的下标为2的时候,发现下标为2的地方已经被占用,那就自动选择下一个地方,比如下标为3,如果为3再继续往下找,直到找到一个空地方为止

ThreadLocal用的就是开放寻执法

拉链法:

在被占用的地方的数据后面,增加一个链表,即每个Entry后面增加存储下一个数据的指针地址,下次查找时,只需要遍历链表即可。

HashMap用的就是拉链法

关于HashMap又有两个知识点:

1、当哈希表后面的链表过长时,遍历是非常耗时的,为了提高效率,当链表长度为8时会自动将该链表转为红黑树

2、当占用容量越多,哈希冲突发生的可能性就越大,为了避免频繁发生哈希冲突,会在占用率达到一定比例时进行扩容,这个比例称之为在HashMap里负载因子,源码里是0.75,而HashMapm默认大小是16,所以当占有率达到12时,就会进行扩容

回到题目

该解题思路是创了两个哈希表,因为数字只可能有10个(0~9),所以直接将数字作为key(虽然没有经历过散列函数的处理,但因为唯一的所以并没问题),再将出现的频率每次增加一即可。

跟Redis里的incr key是一样的处理方式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值