算法学习-哈希表,学会了起码秒50题(持续更新中)

本文写于我的另一篇文章算法学习-前缀和,学会了起码秒50题期间,发现哈希思想不止出现在前缀和的优化中,还经常出现在别的相关题目中,因此有必要针对这种方法好好做个总结。

基础知识

哈希表本质上就是需要理解Hash思想,即可以通过一个key找到一个value,他们俩是一一对应的关系。如何存储这个对应关系,可以通过两种实现方式。

  1. 通过HashMap容器存储,「容器动态增长」,key为索引值,value为索引对应的值,通过map.get(key)就能找到key对应的值。
  2. 通过数组实现哈希表,在索引范围不大的时候,将数组空间开到和索引范围相当,「容量固定」,通过下标随机查找。比方说对于英文26个字母的记录,我们可以new int[26]的数组,通过s.charAt(i)-'a'找到某个字母对应在数组中的下标,从而进行存储与查找。

相关题目

1.两数之和

Hash表存储nums[i]对应的下标i,在搜索的过程中通过target-nums[i]查找对应的下标。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            if(map.containsKey(target-nums[i])){
                return new int[]{map.get(target-nums[i]),i};
            }
            map.put(nums[i],i);
        } 
        return new int[]{-1,-1};
    }
}
1224.最大相等频率

参考题解,主要是采用哈希表记录相关信息,然后分类讨论更新结果。大体思想为,「前缀」提醒我们可以在用下标i遍历数组的过程中,随时考虑起点到i的情况。最长前缀的模式可以分为题解中的四种情况,通过哈希表记录,然后模式匹配,得出最长前缀长度。

class Solution {
    public int maxEqualFreq(int[] nums) {
        int maxlen=(int)1e5+10;
        int[]numTime =new int[maxlen];//记录数字i出现的频度
        int[]freTime =new int[maxlen];//记录出现频度为i的数字的总个数
        int maxfre=0; //记录数字出现的最高频度
        int n=0; //记录目前为止出现的不同数字个数
        int ans=0;
        for(int i=0;i<nums.length;i++){
            int cur=nums[i];
            //统计个数
            if(numTime[cur]==0) n++;
            numTime[cur]++;
            maxfre=Math.max(maxfre,numTime[cur]);
            //统计出现频度数字个数
            freTime[numTime[cur]]++;
            //如果原来已经出现该数字了,原来出现的频度的个数需要-1
            if(numTime[cur]>1) freTime[numTime[cur]-1]--;
            if(n==1||maxfre==1||freTime[maxfre]==1&&freTime[maxfre-1]==n-1||freTime[1]==1&&freTime[maxfre]==n-1){
                //前缀长度为下标+1
                ans=i+1;
            }
        }
        return ans;
    }
}
前缀和相关的题目

前缀和相关的题目中,一直通过哈希表建立快速查找的逻辑,相关题目参考我的另一篇原创文章算法学习-前缀和,学会了起码秒50题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网民工蒋大钊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值