【无标题】

代码随想录算法训练营第六天 | LeetCode242 有效的字母异位词、LeetCode 349 两个数组的交集、LeetCode 202 快乐数、 LeetCode 1. 两数之和


)
哈希表就是通过将作为key的值通过hash运算转换成数组的下标, 然后再在对应下标处传入 key-value键值对
如果多个key经过hash运算之后的下标值一样, 称之为hash碰撞
为了避免hash碰撞, 我们可以让数组 存储的值为链表头, 这样如果发生hash碰撞, 就在对应的链表尾加上对应的 key-value键值对
今天知道的解决办法有两种

  1. 拉链法: 发生hash冲突的值存储在链表中,就是存储元素的数组存储的是链表头, 如果发生hash碰撞, 就在对应的链表尾加上键值对
  2. 线性探测法: 使用线性探测法,一定要保证数组大小要大于要存储的元素个数。如果发生了冲突:就从发生冲突的位置向下寻找一个空位来存储对应值

常见哈希结构

  1. 数组: 数组可以看成key是下标, hash运算为没有操作(可以跟数学种的不变化也是变化的一种联系理解), 而value就是要存储的元素值(存储的不是键值对哟)
  2. hashMap: 存储元素的是数组, 但数组存储的是链表头, 而链表的结构就是键值对(大概
  3. hashSet: 跟hashMap差不多, 存储的也是key-value键值对, hashSet的存储是用hashMap来完成的,每次存储时调用的方法为return map.put(e, PRESENT)==null;PRESENT是个固定值, 也就是说每次存储的值是在key属性里面的, 这也就是为什么hashSet不能存储相同值了吧(如果按照这样的说的话,多次添加的相同的值, 在hashMap里找到的也是相同的键值对, 不会做任何的操作。
    注意:hashMap和hashSet的存储元素的顺序是无序的,遍历也是无序的
    当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法

LeetCode242 有效的字母异位词

题目链接
这道题限制了组成字符串的字母均为小写字母, 又因为在ASCII表中,小写字母都是挨着的, 故可以使用数组

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

也可以使用hashMap

public boolean isAnagram(String s, String t) {

        HashMap<Character, Integer> myHash = new HashMap<>();
        for(int i = 0; i< s.length(); i++){
            char temp = s.charAt(i);
            if(myHash.containsKey(temp)){
                myHash.replace(temp, myHash.get(temp)+1);
            }else{
                myHash.put(temp,1);
            }
        }

        for(int i = 0; i < t.length(); i++){
            char temp = t.charAt(i);
            if(myHash.containsKey(temp)){
                myHash.replace(temp, myHash.get(temp)-1);
            }else{
                return false;
            }
        }

        for(int value : myHash.values()){
            if(value != 0){
                return false;
            }
        }

        return true;
    }

LeetCode 349 两个数组的交集

题目链接
使用hashSet
这是照着官方解法打的, 不愧是官方

public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> mySet1 = new HashSet<>();
        Set<Integer> mySet2 = new HashSet<>();
        for(int num : nums1){
            mySet1.add(num);
        }

        for(int num : nums2){
            mySet2.add(num);
        }

        return getIntersection(mySet1, mySet2);
    }

    public int[] getIntersection(Set<Integer> mySet1, Set<Integer> mySet2) {
        if(mySet1.size() > mySet2.size()){
            return getIntersection(mySet2, mySet1);
        }

        Set<Integer> intersectionSet = new HashSet<>();

        for(int num : mySet1){
            if(mySet2.contains(num)) {
                intersectionSet.add(num);
            }
        }

        int[] intersection = new int[intersectionSet.size()];
        int index = 0;
        for(int num : intersectionSet){
            intersection[index++] = num;
        }

        return intersection;
    }

因为题目说了元素最大值为1000, 故也可以使用数组

public int[] intersection(int[] nums1, int[] nums2) {
        int[] arraySet = new int[1001];
        int[] res = new int[Math.max(nums1.length, nums2.length)];
        int index = 0;
        int size = 0;
        
        for(int i = 0; i < nums1.length; i++){
            int temp = nums1[i];
            if(arraySet[temp] == 0){
                arraySet[temp]++;
            }
        }

        for(int i =0; i < nums2.length; i++){
            int temp = nums2[i];
            if(arraySet[temp] ==1){
                arraySet[temp] -= 2;
            }
        }

        for(int i = 0; i < arraySet.length; i++){
            if(arraySet[i] == -1){
                res[index++] = i;
                size++;
            }
        }

        return Arrays.copyOf(res,size);
    }

LeetCode 202 快乐数

题目链接

public boolean isHappy(int n) {
        Set<Integer> mySet = new HashSet<>();

        while(n != 1 ){
            int temp = 0;
            int sum = 0;
            while(n !=0){
                temp = n % 10;
                n = n / 10;
                sum += temp * temp;
            }
            n = sum;
            if(mySet.contains(sum)){
                break;
            }else{
                mySet.add(sum);
            }
        }

        return n == 1;
    }

LeetCode 1. 两数之和

题目链接

public int[] twoSum(int[] nums, int target) {
        HashMap<Integer, Integer> myHash = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            if( myHash.containsKey(target-nums[i])){
                return new int[]{myHash.get(target-nums[i]), i};
            }else{
                myHash.put(nums[i], i);
            }
        }

        return new int[]{};
        // 或者返回 return new int[0]
    }

今日总结:
用心去感受, 用心去理解, 用心去爱

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值