[哈希表]赎金信

120 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述

原文链接:383. 赎金信
具体描述: 给你两个字符串:ransomNotemagazine ,判断 ransomNote能不能由 magazine里面的字符构成。 如果可以,返回 true;否则返回 falsemagazine中的每个字符只能在 ransomNote使用一次

示例 1:

输入:ransomNote = "a", magazine = "b" 输出:false

示例 2:

输入:ransomNote = "aa", magazine = "ab" 输出:false

示例 3:

输入:ransomNote = "aa", magazine = "aab" 输出:true

提示:

  • 1 <= ransomNote.length, magazine.length <= 10^5
  • ransomNote 和 magazine 由小写英文字母组成

二、思路分析

乍一看这题目,和我们之前做的有效的字母异位词很想哦!异位词就是判断某个字符是否在另外一个字符中存在!跟这题目太符合啦!

第一种方法: 那怎么做那? 首先它只有小写字母,我们可以定义一个长度为26位的int类型数组nt[] records = new int[26];ransomNote简称r,magazine简称m) 我们开始遍历m,每个字符对应的变量名称为c,数组值每次 + 1(records[c - 'a'] = ++records[c - 'a']); 我们再来遍历r,每个字符对应的变量名称为c,索引位置是c - a,先判断r每个字符对应的索引位置的值(records[c - 'a'])是否小于等于0,如果小于等于0,说明这个值在 m中就没有嘛!直接返回false,否则records[c - 'a'] = records[c - 'a'] - 1 这就ok啦!

第二种方法: 可以用数组的方式做!但是我们刚了解了数据结构Map好像也可以哦!跟数组很类似,再次就不赘述啦,代码一看就懂啦~


说一下两者的区别,数组方式是比较快的,因为不会发生链表和红黑数的转换,也不需要通过计算**hashCode**来获取该值对应的位置! **Map**都是需要维护的,所以当数据很大的时候需要维护!


三、AC代码

数组解法(强烈推荐):

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int[] records = new int[26];
        for (char c : magazine.toCharArray()){
            records[c - 'a'] = ++records[c - 'a'];
        }

        for (char c : ransomNote.toCharArray()){
            int index = c  - 'a';
            if (records[index] <= 0){
                return false;
            }else{
                records[index] = records[index] - 1;
            }
        }
        return true;
    }
}

Map解法(稍微有点浪费时间):

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        Map<Character, Integer> map = new HashMap<>();
        for (char c : magazine.toCharArray()){
            if (map.containsKey(c) == true){
                map.put(c, map.get(c) + 1);
            }else {
                map.put(c, 1);
            }
        }

        for (char c : ransomNote.toCharArray()){
            if (map.containsKey(c) == false) {
                return false;
            }else {
                int i = map.get(c) - 1;
                if (i >= 0) {
                    map.put(c, i);
                } else{
                    return false;
                }
            }
        }
        return true;
    }
}

结果对比(截图确实有点不清楚,能理解意思就行哦!): 数组方式: 在这里插入图片描述

map方式: 在这里插入图片描述


四、总结

Map因为需要维护Hash方式存储和链表和红黑数之间的转换,所以还是比较消耗时间的!


感谢大家的阅读,我是Alson_Code,一个喜欢把简单问题复杂化,把复杂问题简单化的程序猿! ❤