代码随想录--哈希表--有效的字母异位词题型

哈希表理论知识补充:

当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。
如果在做面试题目的时候遇到需要判断一个元素是否出现过的场景也应该第一时间想到哈希法!
https://www.programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E5%93%88%E5%B8%8C%E8%A1%A8

哈希表有3种数据结构:
①数组  ②set  ③map
一般数值不多且范围可控时用数组,数值比较多时用set,要key,value对应时用map。
std::unordered_set底层实现为哈希表,std::set 和std::multiset 的底层实现是红黑树,红黑树是一种平衡二叉搜索树,所以key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加。
std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。
当我们要使用集合来解决哈希问题的时候,优先使用unordered_set,因为它的查询和增删效率是最优的,如果需要集合是有序的,那么就用set,如果要求不仅有序还要有重复数据的话,那么就用multiset。
那么再来看一下map ,在map 是一个key value 的数据结构,map中,对key是有限制,对value没有限制的,因为key的存储方式使用红黑树实现的。

有效的字母异位词题型

遇到一个题目,感觉想要用哈希法的时候,先看看能不能用数组,能用数组就尽量用数组,因为数组比较快,你用set的话,你每次放这个key值,你还要做一次哈希运算做一个映射,比数组浪费时间,而且set里面的结构比数组复杂,相比之下用数组做映射更直接的运行速度也是更快的。

学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词

题目规定是小写字母,数值才26个,所以考虑用数组。我们先定义一个数组,并且都等于0。然后做一个for循环字符串s,如遇到a则hash[0]++,然后再做一个for循环字符串t,对上面得出的hash数组,如遇到a则hash[0]--,最终再循环判断得出的hash数组,如果字符串s,t是有效的字母异构词,则最终的hash数组都是0,如果有哪个等于1或者-1等等即不等于0的话就说明字符串s,t不是有效的字母异构词。

这里有点不大懂的是,字符串s如果遇到a则hash[0]++,如果遇到c则hash[2]++,这种对应怎么得出的?
如下图可知,相连的字母ASCLL码相差1,所以s[i]-‘a’,如果s[i]=a,则s[i]-‘a’=0,就是hash[0]++了呀,即字符串s中当前字符为a,那么hash[0]++,就把字母a与hash[0]对应起来了。同理如果s[i]是b,则为hash[1]。

代码随想录--哈希表--有效的字母异位词题型_第1张图片

 大致代码套路:

int hash[26]={0};
for(int i=0;i      hash[s[i]-'a']++;
  }
for(int i=0;i      hash[t[i]-'a']--;
   }
for(int i=0;i<26;i++){
    if(hash[i]!=0)return false;
   }
return true;

你可能感兴趣的:(数据结构与算法,散列表,数据结构)