哈希表是一种将键值联系起来的表,其特点是,比起其他的表来说,他的查询具有很高的效率,因此哈希表也经常被用于查询某些键值中。

1、两数之和

image.png
简单分析,从这里就能看出,可以通过暴力枚举所有的可能,和目标值进行匹配,但是唯一的缺点就是它的时间复杂度为O(n),效率不高,非常的耗时间。

题解一

暴力枚举

  1. class Solution {
  2. public:
  3. vector<int> twoSum(vector<int>& nums, int target) {
  4. vector<int> a;
  5. for(int i=0;i<nums.size();i++){
  6. for(int j=i+1;j<nums.size();j++){
  7. if(nums[i]+nums[j]==target){
  8. a.push_back(i);
  9. a.push_back(j);
  10. break;
  11. }
  12. }
  13. }
  14. return a;
  15. }
  16. };

题解二

哈希表进行取值,这是一种比较巧妙的方式,简单分析。

  • 如果将数组的下标作为key值的话,那哈希表的就退化成了一个数值,这并不符合哈希表的特性。
  • 如果将两个数的下标之和作为hash值的话,那也会造成重复的概率,这样的hash表就不是我们想要的,而且如果hash表中是以链表的形式存储的话,哈希表就有可能会退化成链表。
  • 如果以两个数之和也就是target,作为hash值的话,依照题目的条件,那相同的可能性就很低了,而且我们可以刚好高效的匹配到我们想要的key值,但是,问题在于,我们通过hash值找到的value只能是一个,并且因此,这样的方式是错误的

以上是我的推导,根据这三种可能性,我想不到有任何能够做出一张令人满意的hash表,但是,我看完题解后,可能有时候,答案的来源,需要一些灵性罢了。
这是将一个数的值和另一个数的数值下标进行结合,这种结合方式巧妙的利用target作为两个数之间的中间桥梁,
另一个数,等于target减去这个数,并且把另一个数(target-num)作为key值,value为数组下标。
当我们获取到另外一个数是,刚好可以通过这个数,访问到原来减去的那个数的数组下表

  1. class Solution {
  2. public:
  3. vector<int> twoSum(vector<int>& nums, int target) {
  4. map<int,int> table;
  5. vector<int> res(2);
  6. for(int i=0;i<nums.size();i++){
  7. if(table.count(nums[i])){
  8. res[1]=i;
  9. res[0]=table[nums[i]];
  10. return res;
  11. }
  12. table[target-nums[i]]=i;
  13. }
  14. return res;
  15. }
  16. };

3、无重复的字符的最长子串

image.png
由于是字符,很容易就想到字典树或者是哈希表来处理这类问题,由于我用的是java中的hashmap去处理这个问题,设置一个index=0,遍历这个字符串,将每个字符加入的哈希表中,记录个数,当哈希表中存在字符是,记录最大个数,将哈希表删除,index++,从不同起始位置去查看字符,这样的遍历方式是O(n),及其耗费时间。

题解一 哈希表

  1. class Solution {
  2. public int lengthOfLongestSubstring(String s) {
  3. int count=0;
  4. int max=0;
  5. int index=0;
  6. Map<Character, Integer> map=new HashMap<>();
  7. for(int i=index;i<s.length();i++){
  8. if(map.get(s.charAt(i))!=null){
  9. if(count>max)
  10. max=count;
  11. count=0;
  12. map.clear();
  13. i=++index;
  14. }
  15. map.put(s.charAt(i),1);
  16. count++;
  17. }
  18. if(count>max)
  19. max=count;
  20. return max;
  21. }
  22. }