代码随想录算法训练营第六天 | 哈希表part01

本文介绍了如何使用哈希表解决四个编程问题:判断有效字母异位词(基于频率数组),寻找两个数组交集(使用set),检测快乐数(避免死循环),以及查找两数之和(使用哈希map)。重点讲解了哈希表的原理和在这些问题中的应用。
摘要由CSDN通过智能技术生成

题目:

242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和


学习内容:

哈希表理论基础

哈希表是根据关键码的值而直接进行访问的数据结构,表现为键值对。 一般哈希表用来判断一个元素是否出现在集合里。其实就是适合通过O(1)的时间复杂度直接查询指定元素
下图是利用哈希函数由key求value的过程:
在这里插入图片描述
但是这也可能存在哈希碰撞的情况:
在这里插入图片描述

242.有效的字母异位词

这道题我们使用数组来解决问题,数组的值表示字母出现的频率,索引表示第1-26个字母。

class Solution {
    public boolean isAnagram(String s, String t) {
        int[] record = new int[26]; // 定义一个长度为26的数组,记录每一个字母出现的次数
        // 字符串s录入频数
        for (int i = 0; i < s.length(); i++) {
            record[s.charAt(i) - 'a']++;
        }
        // 字符串t录入频数
        for (int i = 0; i < t.length(); i++) {
            record[t.charAt(i) - 'a']--;
        }
        // 遍历record,看是否有非0,有则返回false
        for (int count:record) {
            if (count != 0) {
                return false;
            }
        }
        return true;
    }
}

时间复杂度:O(m+n)或O(n),两个循环
空间复杂度:O(1),因为record长度恒定。

349. 两个数组的交集

这道题的关键是,什么时候用set什么时候用数组。题目中需要输出的元素是不重复的,使用set。如果是size固定的输入,则可以考虑数组。

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> hashset_1 = new HashSet<>();
        Set<Integer> hashset_res = new HashSet<>();
        for (int i : nums1) {
            hashset_1.add(i);
        } 
        for (int i : nums2) {
            if (hashset_1.contains(i)) {
                hashset_res.add(i);
            }
        }
        // 将hashset转为int[]
        int[] res = new int[hashset_res.size()];
        int j = 0;
        for (int i : hashset_res) {
            res[j++] = i;
        }
        return res;
    }
}

时间复杂度:O(n)
空间复杂度:O(n),hashset_res是动态的

202.快乐数

这题有一个难点,就是不仅仅是要取一个n的各位的数,其次还要判断到底会不会陷入死循环。这时候需要存储所有的sum值,来判断是否有重复的,有就说明死循环了。

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> hashset = new HashSet<>();
        while (n != 1) {
            int sum = 0;
            while (n != 0) {
                sum += (n % 10) * (n % 10);
                n = n / 10;
            }
            if (!hashset.contains(sum)) {
                hashset.add(sum);
            } else {
                return false;
            }
            n = sum;
        }
        return true;
    }
}

1.两数之和

暴力法(略)。
使用hashmap。我们要查找的是元素是否出现过,所以元素对应key,下标对应输出的value。

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

学到了什么

  • 哈希表(Hash table)三种常见的结构:数组,set(集合),map(映射)。
    其中set存储的元素不可重复,map使用key-value存储,非常适合用key来搜索。
  • 求set的大小:HashSet.size();
    判断是否含有某个元素:HashSet.contains(a);
    添加和移除元素: HashSet.add(); HashSet.remove();
    通过set接口来声明变量:Set <Integer> hashset_1 = new HashSet<>(); 降低代码的耦合性.
  • **当我们要判断一个元素是否出现在集合中时,要想到哈希法。**判断有无重复的用hashset。
  • 对一个数字 取每一位,n = n % 10; n = n / 10;

学习时间:

2024.3.11

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值