算法训练营day6

一、哈希表理论基础
  1. 哈希表解决的问题:一般哈希表都是用来快速判断一个元素是否出现集合里
  2. 本质是用空间换时间,因为还要使用数组,set,map来保存 原值和hash值的对应关系
  3. 哈希函数
    1. 案例:将学生姓名投射成哈希表上的索引,进而快速判断表中是否存在该学生
    2. 如果hash值大于tableSize怎么办?取模
    3. 如果学生数量大于tableSize怎么办?(两个学生名投射到哈希表同一位置上)哈希碰撞就引出来了
    4. 如何解决哈希碰撞?拉链法和线性探测法
      1. 拉链法,在冲突位置在保存一个链表在这里插入图片描述

      2. 线性探测法

        1. 前提条件:保证tableSize 大于 dataSize
        2. 小王和小李冲突了,那么就向下寻找空位放置小王在这里插入图片描述
二、有效的字母异位词
class Solution {
    public boolean isAnagram(String s, String t) {
        //如果 两字符串长度不相等,那么一定不是字母异位词
        if (s.length()!= t.length()) return false;
        HashMap<Character, Integer> dic = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            // 这一行是向 map中 key为 s.charAt(i) 的对应 value + 1
            dic.put(s.charAt(i) , dic.getOrDefault(s.charAt(i), 0) + 1);
            // 这一行是向 map中 key为 s.charAt(i) 的对应 value - 1
            dic.put(t.charAt(i) , dic.getOrDefault(t.charAt(i), 0) - 1);
        }
        //如果两个字符串中字符组成相等,那么最后map中所有数据的value值都为0,不为0则表示s t 不是字母异位词
        for (int val : dic.values()) {
            if (val != 0)
                return false;
        }
        return true;
    }
}
三、两个数组的交集

假设有数组1,2

  1. 两个集合 Set1,Set2,遍历其中一个数组加入到set1中

  2. 在遍历另外一个数组时判断set中是否存在该数

  3. 如果存在,则添加到set2中

  4. 再以set大小创建一个新数组,遍历set加入到数组中返回即可

    1. 注意set无法用索引遍历
  5. //给定两个数组 nums1 和 nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 
    //
    // 
    //
    // 示例 1: 
    //
    // 
    //输入:nums1 = [1,2,2,1], nums2 = [2,2]
    //输出:[2]
    // 
    //
    // 示例 2: 
    //
    // 
    //输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
    //输出:[9,4]
    //解释:[4,9] 也是可通过的
    // 
    //
    // 
    //
    // 提示: 
    //
    // 
    // 1 <= nums1.length, nums2.length <= 1000 
    // 0 <= nums1[i], nums2[i] <= 1000 
    // 
    //
    // Related Topics 数组 哈希表 双指针 二分查找 排序 👍 899 👎 0
    
    
    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        public int[] intersection(int[] nums1, int[] nums2) {
    
            if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
                return new int[0]; //长度为0的空数组
            }
            Set<Integer> set1 = new HashSet<>();
            Set<Integer> resSet = new HashSet<>();
            //遍历数组1
            for (int i : nums1) {
                set1.add(i);
            }
            //遍历数组2的过程中判断哈希表中是否存在该元素
            for (int i : nums2) {
                if (set1.contains(i)) {
                    resSet.add(i);
                }
            }
    
            //方法1:将结果集合转为数组
    
    //        return resSet.stream().mapToInt(x -> x).toArray();
    
            //方法2:另外申请一个数组存放setRes中的元素,最后返回数组
            int[] arr = new int[resSet.size()];
            int j = 0;
            for(int i : resSet){
                arr[j++] = i;
            }
    
            return arr;
        }
    }
    
    
四、快乐数

有些许类似之前环形链表二那道题,这里用的是“隐形环”,当计算过程中同一个数字出现两次时,由于每一次数字迭代的计算逻辑相同,那么这个数是不会达到 “1”,也就不是快乐数

计算快乐数逻辑,每次提取出个位,然后总体除以 10 去除 个位,不断遍历计算

        while(n > 0){
            int d = n % 10;
            n = n / 10;
            totalSum += d*d;
        }
五、两数之和
  1. 创建一个HashMap,用来保存已遍历完成但暂时没有找到存在两数和为target的数字

    1. 比如 target为 10 ,nums[2,4,5,8,…],先保存2,因为还没有遍历到8,8没有存到map中
    2. key对应数组中索引,值为数组中的值,
      数之和
  2. 创建一个HashMap,用来保存已遍历完成但暂时没有找到存在两数和为target的数字

    1. 比如 target为 10 ,nums[2,4,5,8,…],先保存2,因为还没有遍历到8,8没有存到map中
    2. key对应数组中索引,值为数组中的值,
  3. 进行for循环,如果map中存在 target - num[i],则返回当前索引和target - num[i]对应索引

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值