刷题笔记(六)--哈希表:基础题目和思想

系列文章目录

刷题笔记(一)–数组类型:二分法
刷题笔记(二)–数组类型:双指针法
刷题笔记(三)–数组类型:滑动窗口
刷题笔记(四)–数组类型:模拟
刷题笔记(五)–链表类型:基础题目以及操作

哈希表基础

这篇博客中的题都是基础的题,主要就是为了让刷题的我们体会一下哈希思想和哈希表的便利性。本来是想在这里再写一遍关于哈希表的思想和设计原理的,但是之前写过这篇博客,所以这里就直接放链接了。
数据结构–哈希表
当然,这里是单单关于Map的,Set没有提及。

Map

这部分是关于Map的。

242.有效的字母异位词

题目链接如下:

242. 有效的字母异位词
在这里插入图片描述

我这里先上代码然后讲解吧

public class 有效的字母异位词 {
    //第一个反应就是用一个数组来进行存储,因为ASCALL码的原因,所以应该是可以完好的遍历的,然后遍历数组中的每个元素是否相等就行
    //第二个反应就是用哈希表,然后遍历哈希表中的元素,再一一比较
    public boolean isAnagram(String s, String t) {
        HashMap<Character,Integer> sMap = new HashMap();
        HashMap<Character,Integer> tMap = new HashMap();
        //用一个哈希表来记录s中每个字符出现的次数
        for(char c:s.toCharArray()){
            sMap.put(c,sMap.getOrDefault(c,0)+1);
        }
        //遍历t然后如果sMap里面有相同的,就-1
        for(char c:t.toCharArray()){
            sMap.put(c,sMap.getOrDefault(c,0)-1);
        }
       for(Integer i:sMap.values()){
           if(i != 0){
               return false;
           }
       }
        return true;
    }
}

和我代码中的注释一样,我第一个反应就是暴力循环,每一个的下标都往后循环一次,看有没有可以匹配的上的。但是这样无疑就很麻烦。所以这里用Map的思想,用一个哈希表来储存键值对<数组中的元素,元素目前出现的次数+1>,然后先遍历字符串s,获取到出现了的元素和元素出现的次数。接着遍历字符串t,还是上面的哈希表,但是这次是把出现了的元素-1。最后看有没有元素总的出现次数不是0的。

383. 赎金信

题目链接如下:

383. 赎金信

题目截屏如下:
在这里插入图片描述

这道题和上面的题很像的。上面的题是判断两个字符串当中的组成字符是否一致,而这道题则是判断magazine是否包含了另外一个字符串。还是一样的思路,不过就是判断条件要稍微改一下下。
但是这里其实是有一个问题的,就是用空间换时间真的值得嘛?这里数据比较小,所以体现不出来差距,数据大了那区别就大了。所以这里我们用哈希思想来实现就好了。但是我们就不用哈比表了,就用数组来存储每个元素出现的次数,对应的下标就是每个字符对应的ASCALL码下标。

public class 赎金信 {
    public boolean canConstruct(String ransomNote, String magazine) {
    	//这里其实也可以用26个大小的,我图后面方便,就直接设置了100
        int[] key = new int[100];
        for(char c:magazine.toCharArray()){
        	//如果设置了大小为26,那么就是key[c - 'a'],下面一样
            key[c] += 1;
        }
        for (char c:ransomNote.toCharArray()){
            key[c] -= 1;
            //减了之后发现如果说有<0的值,那就证明不能完全包含。
            if(key[c] < 0){
                return false;
            }
        }
        return true;
    }
}

Set

349. 两个数组的交集

题目链接如下:

349. 两个数组的交集

题目截屏如下:
在这里插入图片描述
关于这道题思路就很明确,我们就要使用Set来进行存储,毕竟它的特点就是不允许相同元素的存在。

public class 两个数组的交集 {
    public int[] intersection(int[] nums1, int[] nums2) {
    	//先进行条件少筛选
        if((nums1==null)||(nums1.length==0)||(nums2==null)||(nums2.length==0)) {
            return new int[0];
        }
        //第一个set用来记录num1中出现的数字
        HashSet<Integer> set1=new HashSet<>();
        //第二个set用来筛选相同的数字
        HashSet<Integer> set2=new HashSet<>();
        for(int i:nums1) {
            set1.add(i);
        }
        for(int i:nums2)
        {
            if(set1.contains(i))
                set2.add(i);
        }
		//筛选完成后就直接创建个数组开始赋值就好了。
        int[] temp=new int[set2.size()];
        int index=0;
        for(int i:set2)
        {
            temp[index++]=i;
        }
        return temp;
    }
}

202. 快乐数

题目链接如下:

202. 快乐数

题目截屏如下:
在这里插入图片描述

很简单的题,主要就是分清/10和%10的使用场景和意义。

public class 快乐数 {
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<>();
        while(n != 1){
            int res = fun(n);//res记录平方相加的和
            if(set.contains(res)){
                return false;//如果说这个和在set这个集合当中已经是存在的,那就是陷入了一个死循环
            }
            //如果不存在,那就加入就好
            set.add(res);
            n = res;
        }
        return true;
    }
    //设置函数来获得当前数字每一个位数的平方相加的和
    public int fun(int n){
        int res = 0;
        while(n > 0){
            int tmp = n % 10;
            n /= 10;
            res += tmp * tmp;
        }
        return res;
    }
}

总结

emmmmm,加快进度吧。数据结构这里还有栈和队列以及二叉树呢。数据结构完了之后就赶快进入算法了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值