大部人没有深入接触过哈希表,仅仅知道哈希表是存放键值对的,必须一个键对应一个值,其实不然,哈希表有三种常见的表现形式:
1.哈希数组(实质上就是数组)
2.Set,Set是一个接口,其中一种形式就是以哈希表实现的 ,特点是只存放不重复的元素
3.Map,Map也是夜歌接口,其中一种形式也是用哈希表实现的,存储的是键值对
242.有效的字母异位词
题目链接/文章讲解/视频讲解: 有效的字母异位词
思路:题目就是让判断两个字符串中每个字母出现的次数是否相等,如:s="abba" , t="baba" true s="aabc" , t="abc" false
思路:字符串是由字母组成的,每个字母都有对应的ASCII码,那么本题就可以用哈希数组arr来解决,长度为26,因为a~z只有26个字母。
将字符映射到数组的索引下标上,a映射的下标为0,b映射的下标为1 以此类推直到 z映射的下标为25
首先遍历s,arr[ s[i] - 'a' ]++, 其中s[i] - 'a'表示,遍历到的字母在0~25之间对应的下标
如arr['b' - 'a']++ ,‘b’-'a'=1,表示arr[1]++,即b字母每出现一次 arr[1]就自增1
然后遍历t, arr[ t[i] - 'a' ]--, 即在arr数组中减去t中出现的字母,最后遍历arr,如果存在元素>0,那么就返回false,如果arr中元素全为0,就说明s中有的字母,t中全部都有,返回true。
349. 两个数组的交集
题目链接/文章讲解/视频讲解:两个数组的交集
思路:这道题的返回结果是去重的,即如果有重复的元素,返回一个就可以了。这道题就用到了哈希数据结构中的Set,以哈希表的形式实现,因为Set本身的特点就是不能添加重复的元素。
首先定义两个Set结构体:set,reSet。 遍历nums1,将nums1的值存入set中。然后遍历nums2,用Set接口中定义的方法boolean contains(Object o):如果集合中包含指定的元素,则返回 true。判断set中是否存在nums2中对用的元素,如果存在,那么将该元素添加到reSet中,直接用reSet.add(nums2[i])添加,最后返回reSet即可。
202. 快乐数
题目链接/文章讲解/视频讲解:快乐数
思路:本题第一个难点:每个位置上的数字的平方和sum如果重复出现,那么就陷入了循环,说明不是快乐数,所以就需要将每次的平方和存储起来,如果某次计算的平方和出现过,就返回false。
第二个难点:如何获取每个位置上的数字。
判断sum是否重复出现就用set
Set<Integer> record = new HashSet<>(); while (n != 1 && !record.contains(n)) { record.add(n); n = getNextNumber(n); }
获取每个位置的数字,并计算平方和,用sum存储
private int getNextNumber(int n) { int res = 0; while (n > 0) { int temp = n % 10; res += temp * temp; n = n / 10; } return res;
1. 两数之和
题目链接/文章讲解/视频讲解:两数之和
思路:用哈希表将nums1[i]作为键,i(下标)作为值,映射到哈希表中,通过遍历数组,在哈希表中寻找是否存在 target-nums[i]的差值,如果存在,记录下标i,以及差值(键)在哈希表中的数值(就是下标)。如果不存在,将nums[i],i存入哈希表,继续遍历数组。