代码随想录算法训练营第5天| ● 哈希表理论基础 ● 242.有效的字母异位词 ● 349. 两个数组的交集 ● 202. 快乐数● 1. 两数之和

哈希表理论基础

文章链接

哈希表理论基础

哈希表:哈希表是根据关键码的值而直接进行访问的数据结构(关键码就是数组的索引下标,然后通过下标直接访问数组中的元素)

哈希表解决的问题:一班用来判断一个元素是否出现在集合中

哈希函数

通过hashCode把名字转化为数值,一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值,这样就把学生名字映射为哈希表上的索引数字了。

哈希碰撞

即出现多个元素指向同一个索引

哈希碰撞解决方法

1.拉链法:(数组+链表)

线性探测法:

一定要保证tableSize大于dataSize。 我们需要依靠哈希表中的空位来解决碰撞问题

常见的哈希结构

  • 数组
  • set(HashSet,TreeSet)
  • map(hashMap.TreeMap)

总结:

总结一下,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法

但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。

有效的字母异位词

题目链接:

LeetCode_242

视频链接:

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

思路:

利用数组arr(size=26)存储字符串每个字符出现的次数,然后遍历另一个字符串,字符出现一次就arr对应-1,最后遍历arr数组,如果都是0说明就是有效的字母异位词

代码:

public static boolean isAnagram(String s, String t) {
        int []arr=new int[26];
        char[] char_s = s.toCharArray();
        char[] char_t = t.toCharArray();
        for (int i = 0; i <char_s.length ; i++) {
           arr[char_s[i]-'a']++;
        }
        for (int i = 0; i <char_t.length ; i++) {
            arr[char_t[i]-'a']--;
        }
        for (int i = 0; i <arr.length ; i++) {
            if(arr[i]!=0){
                return false;
            }
        }
        return true;
    }

两个数组的交集

题目链接:

LeetCode_349

视频链接:

学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集

思路:(主要考察,在需要去重操作 的时候用到set)

利用set对两个数组进行去重,然后遍历去重后的数组,利用set.contains方法看是否纯在相同元素

代码:

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        HashSet<Integer> set1 = new HashSet<>();
        HashSet<Integer> set2 = new HashSet<>();
        for (int i = 0; i < nums1.length ; i++) {
            set1.add(nums1[i]);
        }
        for (int i = 0; i < nums2.length ; i++) {
            if(set1.contains(nums2[i])){
              set2.add(nums2[i]);
            }
        }
        Iterator<Integer> iterator = set2.iterator();
        int[]ans=new int[set2.size()];
        int i=0;
        while (iterator.hasNext()) {
            Integer next =  iterator.next();
            ans[i++]=next;
        }
        return ans;
    }
}

快乐数

题目链接;

LeetCode_202

思路:

根据题目利用循环进行模拟,由题目可以知道,重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1,所以利用set保存n,如果n已经存在,那么最后判断n是否等于1就知该数是不是快乐数

代码:

class Solution {

     public int cal(int n){
        int sum=0;
        while (n>0){
            int num=n%10;
            sum+=num*num;
            n/=10;
        }
        return sum;
    }
    public boolean isHappy(int n) {
    HashSet<Integer> set = new HashSet<>();
        while (n!=1&&!set.contains(n)){
            set.add(n);
            n=cal(n);
        }
        return n==1;
    }
}

两数之和

题目链接:

LeetCode_01

思路:

本题呢需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是 是否出现在这个集合。

那么我们就应该想到使用哈希法了。

因为本题,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适

代码

class Solution {
    public int[] twoSum(int[] nums, int target) {
          int[] ans = new int[2];
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(target - nums[i])) {
                ans[1] = map.get(target-nums[i]);
                ans[0] = i;
                break;
            }
                map.put(nums[i], i);
        }
        return ans;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值