leetcode 刷题_day05_哈希表01_快速查值

242.有效的字母异位词

思路

判断两个字符串每个字符出现的次数是否都相同 --> 存储这两个字符串各个字母出现的次数并判断 --> 一个字符串存,一个字符串减
重点:

  1. 需要能快速获取指定字符的数量 --> 哈希表
  2. 如果最后所有字符的数量总和为 0,则两字符串为异位词

解题方法

依照哈希表的原理,可以使用数组来实现
索引通过字母ascii码相对 a的位置来确定

复杂度

  • 时间复杂度:
    O ( n ) O(n) O(n)

  • 空间复杂度:
    O ( 1 ) O(1) O(1)

Code

Java

class Solution {
    public boolean isAnagram(String s, String t) {
        
        // 哈希表存储s字段各个字母的个数,然后t字段删减
        // 根据哈希表的原理,用数组存字母个数,用字母ascii码与a的相对位置作为数组索引

        int[] record = new int[26];

        // s 字符串往 record 新增
        for (int i = 0; i < s.length(); i++) {
            record[s.charAt(i) - 'a']++;
        }
        // t 字符串往 record 删减
        for (int i = 0; i < t.length(); i++) {
            record[t.charAt(i) - 'a']--;
        }

        // 遍历 record,判断总和是否为 0,为 0 则符合字母异位词
        for (int sum: record) {
            if (sum != 0) {
                return false;
            }
        }

        return true;
    }
}

349. 两个数组的交集

思路

输入数组数据范围、个数可控,可以使用基于数组的哈希表

解题方法

  1. 构建两个基于数组的哈希表,存储输入的数组都有什么数
  2. 将都有的数值放到列表中(长度不定),然后转成数组输出

复杂度

  • 时间复杂度:
    O ( n ) O(n) O(n)

  • 空间复杂度:
    O ( 1 ) O(1) O(1)

Code

Java

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        // 输入数组数据范围、个数可控,可以使用基于数组的哈希表

        // 索引为输入数组的数值
        int[] record1 = new int[1001];
        int[] record2 = new int[1001];
        List<Integer> result = new ArrayList<>();

        // 分别记录各自数组都有什么数
        for (int num: nums1) {
            record1[num]++;
        }
        for (int num: nums2) {
            record2[num]++;
        }

        // 将有数的记录到result中,转换为数组输出
        for (int i = 0; i < record1.length; i++) {
            if (record1[i] != 0 && record2[i] != 0) {
                result.add(i);
            }
        }

        return result.stream().mapToInt(x -> x).toArray();
    }
}

202. 快乐数

思路

  1. 判断是否循环则需要记录历史数据,且要能 O(1) 时间内找到,而且这历史记录的数据量不清楚 --> 哈希表
  2. 计算逻辑 --> 取给定数值的各个位数上的值

解题方法

HashSet
取模

复杂度

  • 时间复杂度:
    O ( l o g n ) O(logn) O(logn)

  • 空间复杂度:
    O ( l o g n ) O(logn) O(logn)

Code

Java

class Solution {
    public boolean isHappy(int n) {
        
        // 判断是否循环 --> 判断sum是否重复 --> 哈希表
        Set<Integer> record = new HashSet<>();
        while(n != 1 && !record.contains(n)) {
            record.add(n);
            n = generateHappyNum(n);
        }
        return n == 1;
    }

    private int generateHappyNum(int n) {
        int result = 0;

        // 通过循环取模,实现按位数取值
        while(n > 0) {
            int temp = n % 10;
            // 平方和
            result += temp * temp;
            n = n / 10;
        }

        return result;
    }
}

1. 两数之和

思路

遍历输入的数组,对每个数,都去哈希表查一下有没有所需的数,如果没有,则把自己存进去,如果有,则返回

  1. 哈希表需要能存储键值对 --> 值,索引
  2. 能不受限存
    所以使用 HashMap

复杂度

  • 时间复杂度:
    O ( n ) O(n) O(n)

  • 空间复杂度:
    O ( n ) O(n) O(n)

Code

Java

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 遍历输入的数组,对每个数,都来 record 查一下有没有所需的数,如果没有,则把自己存进去,如果有,则返回
        // <数值,索引>
        Map<Integer, Integer> record = new HashMap<>();

        for(int i = 0; i < nums.length; i++) {
            int need = target - nums[i];
            Integer needIndex = record.get(need);
            if (needIndex != null) {
                return new int[]{i, needIndex};
            }
            record.put(nums[i], i);
        }

        return new int[0];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值