【LeetCode】No.383. Ransom Note -- Java Version

题目链接: https://leetcode.com/problems/ransom-note/

1. 题目介绍(勒索信)

Given two strings ransomNote and magazine, return true if ransomNote can be constructed from magazine and false otherwise.
【Translate】:给定两个字符串ransomNotemagazine,如果ransomNote可以从通过magazine中的字符构造出来(换句话说就是,magazine相当于一个字符库,ransomNote则需要从magazine中取字符;其实也就是一个判断单个字符数量的问题),则返回true,否则返回false。

Each letter in magazine can only be used once in ransomNote.
【Translate】:magazine中的每个字母只能在ransomNote中使用一次。

测试用例:
【LeetCode】No.383. Ransom Note -- Java Version_第1张图片
约束:
  约束要求ransomNote和magazine的长度不小于1,且不大于10五次方;同时还要求字符串内容都是小写字母。
Constraints

2. 题解

2.1 Python Version

  拿到这个题的时候,一开始其实我并没有理解它的意思,只是单纯觉得是判断magazine中是否包含ransomNote。心想要是这样,用python岂不是很简单。于是就有了下面的代码:

class Solution(object):
    def canConstruct(self, ransomNote, magazine):
        """
        :type ransomNote: str
        :type magazine: str
        :rtype: bool
        """
        if ransomNote in magazine:
            return True
        else:
            return False

  上来直接判断一下不就完了,结果提交的时候傻眼了,小丑竟是我自己。这道题虽然是说magazine包含ransomNote,但不是整体包含,而是跟旧日历一样,一次对应一个,用完就撕掉(比喻的可能不太准确,但大概就是这个意思),所以我们真正要判断的是字符串中单个字符的数量。
在这里插入图片描述
正确代码如下所示:

class Solution(object):
    def canConstruct(self, ransomNote, magazine):
        """
        :type ransomNote: str
        :type magazine: str
        :rtype: bool
        """
        for i in set(ransomNote):
            if magazine.count(i) < ransomNote.count(i):
                return False
        return True

  Python以其特有的count()函数可以统计出某个字符在该字符串中出现的次数,当然这在便捷的同时也牺牲了时间。
【LeetCode】No.383. Ransom Note -- Java Version_第2张图片

2.2 数组方式(ASCII码相减定位)

  仿照Python实现该题的思想,通过一个数组来记录单字符在magazine中出现的次数,然后遍历ransomNote,减去ransomNote中出现的字符数量,最后就只需要判断一下该位置的数是否小于0即可。

    public boolean canConstruct1(String ransomNote, String magazine) {
        int[] count = new int[26];  // 定义数组完毕后,自动初始化为0
        int i,s = 0;
        
        for(i = 0; i < magazine.length(); i++){
            s = magazine.charAt(i) - 'a';
            count[s] += 1; 
        }
        
        for(i = 0; i < ransomNote.length(); i++){
            s = ransomNote.charAt(i) - 'a';
            count[s] -= 1; 
            if(count[s] < 0 ){
                return false;
            }
        }
        return true;
    }

【LeetCode】No.383. Ransom Note -- Java Version_第3张图片
  我们可以看到上面虽然得到了较好的时间,但是在空间上还有很大的优化空间。于是,查询到了如下题解,其基本思想都是一样的,但其通过了减少变量,达到了优化空间的目的。

     public boolean canConstruct2(String ransomNote, String magazine) {
        int[] arr = new int[26];
        for (int i = 0; i < magazine.length(); i++) {
            arr[magazine.charAt(i) - 'a']++;
        }
        for (int i = 0; i < ransomNote.length(); i++) {
            if(--arr[ransomNote.charAt(i)-'a'] < 0) {
                return false;
            }
        }
        return true;
    }

【LeetCode】No.383. Ransom Note -- Java Version_第4张图片

2.3 HashMap

  关于HashMap这方面,并没有做过多的思考,只是简单的通过HashMap的方式把2.2中数组的思想实现出来了,唯一需要注意的地方就是,在遍历ransomNote的时候需要先判断一下HashMap中是否存在这个键,如果不存在,但是你下面又要对它进行操作,就会报错。
  此外还有一个疑问就是,为什么明明HashMap要比数组快,但为什么时间上不如数组要好?这是因为HashMap的快只体现在插入和删除的时候,而在查询的时候因为数组有下标所以在查询集合中某个元素时,一般都会对数组甘拜下风。

   public boolean canConstruct(String ransomNote, String magazine) {
        if(magazine.length()<ransomNote.length())
            return false;
        int i,s = 0;
        HashMap<Integer,Integer> count= new HashMap<>();
        
        for (i = 0; i < magazine.length(); i++) {
            s = magazine.charAt(i) - 'a';
            count.put(s, count.getOrDefault(s,0)+1);
        }
        for (i = 0; i < ransomNote.length(); i++) {
            s = ransomNote.charAt(i) - 'a';
            if(count.containsKey(s)){
                count.replace(s,count.getOrDefault(s,0)-1);
                if(count.get(s) < 0){
                    return false;
                }
            }else{
                return false;
            }
        }    
        return true;
    }

【LeetCode】No.383. Ransom Note -- Java Version_第5张图片

3. 可参考

[1] java数组的初始化
[2] hashmap和数组哪个速度快
[3] python中函数COUNT()的功能是什么
[4] Java 数组
[5] Java HashMap
[6] arr[0]++和++arr[0]之间的差异
[7] java 统计字符串中每个字符出现的次数(数组或HashMap实现)
[8] Java在线测试工具

你可能感兴趣的:(leetcode,算法,Easy)