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

242. 有效的字母异位词

leetcode
文档讲解
视频讲解

题目中关于 “异位词” 的定义:两字符串中每个字符出现的次数都相同,则两个字符串互称为异位词。

得到重要信息,字符串长度相等,并且出现的字符种类和数量也相等。因此可以使用哈希表存储一个字符串中每个字符出现的数量,然后再遍历另一个字符串,将出现在哈希表中的字符的数量 -1,如果最后哈希表中各个字符的数量都为 0,说明两个字符串出现的字符的种类和数量相等。

因为 s、t 都是小写字母,因此可以用长度为 26 的数组作为哈希表。

class Solution {
    public boolean isAnagram(String s, String t) {
        // 长度不相等,不是异位词
        if (s.length() != t.length()) return false;

        // 哈希表
        int[] records = new int[26];

        // 统计 s 中各字符出现的次数
        for (char c: s.toCharArray()) {
            records[c - 'a']++;
        }

        // 遍历 t,削减哈希表中该字符的数量
        for (char c: t.toCharArray()) {
            records[c - 'a']--;
            // 如果数量变为了负数,说明 s 中 c 字符的数量不够,所以不是异位词
            if (records[c - 'a'] < 0) return false;
        }

        // 如果还有某些字符的数量大于零,说明 s 中某个字符的数量大于 t,因此不是异位词
        for (int i: records) {
            if (records[i] > 0) return false;
        }

        return true;
    }
}

349. 两个数组的交集

leetcode
文档讲解
视频讲解

交集就是查看一个集合中的哪些元素在另一个集合中。因此可以先用哈希表存储一个集合中的元素,然后再遍历另一个集合,把相同的元素存起来,存起来的元素可以用哈希表去重。

class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
    Set<Integer> nums1Set = new HashSet<>();
    Set<Integer> resSet = new HashSet<>();

    // 先存储 nums1 中出现的数字
    for (int num: nums1) {
        nums1Set.add(num);
    }

    // 再遍历 nums2,看看 nums1Set 中是否存在,存在就是相交的元素,存起来
    for (int num: nums2) {
        if (nums1Set.contains(num)) {
            resSet.add(num);
        }
    }

    // 整理结果集,转为数组
    int[] res = new int[resSet.size()];
    int i = 0;

    for (int num: resSet) {
        res[i++] = num;
    }

    return res;
}

题目中,nums[i] 的范围在 0 ~ 1000,因此哈希表也可以采用长度为 1000 的数组,数组值就是 0 和 1,0 表示集合中没出现这个数字,反之则出现过。

202. 快乐数

leetcode
文档讲解

n 的范围是 1 ~ 2^31-1,最多十位数,如果每位数字都是 9(虽然 10 个 9 已经超出范围了),平方和也才是 810,也就是说对 n 求出的各位数字的平方和的范围可以 简单理解为 1 ~ 810。所以平方和是有界的,无限循环一定是某些 sum 重复了,sum 不会是无限循环不重复的值。因此可以使用哈希表存储 sum,如果再次出现,说明会无限循环,不是快乐数,当然也可以使用一个长度为 810 的数组当作哈希表。

class Solution {
    public boolean isHappy(int n) {
        // 存放已求出的和
        Set<Integer> set = new HashSet<>();
        // int[] set = new int[810];

        while(true) {
            // 计算各位的平方和
            int sum = getSum(n);

            // 1,是快乐数
            if (sum == 1) return true;

            // sum 出现过,会无限循环
            if (set.contains(sum)) return false;
            // if (set[sum] == 1) return false;

            // 存起来,继续求和
            set.add(sum);
            // set[sum] = 1;
            n = sum;
        }
    }

    // 求各位的平方和
    public int getSum(int n) {
        int sum = 0;
        while (n > 0) {
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }
}

1. 两数之和

leetcode
文档讲解
视频讲解

使用哈希表,然后遍历数组,去哈希表里面查找差值,如果差值在哈希表里面,则找到一个解。

class Solution {
public int[] twoSum(int[] nums, int target) {
    // 存储遍历过的值
    Map<Integer, Integer> map = new HashMap<>();

    for (int i = 0; i < nums.length; i++) {
        // 去哈希表中看看有没有值和当前值加起来等于目标值
        if (map.containsKey(target - nums[i])) {
            // 有,则返回两个值的下标
            return new int[]{i, map.get(target - nums[i])};
        } else {
            // 否则将当前值及其下标放进哈希表
            map.put(nums[i], i);
        }
    }

    // 没找到
    return new int[]{-1, -1};
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注