[题目]
Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false.
Each letter in the magazine string can only be used once in your ransom note.
You may assume that both strings contain only lowercase letters.
canConstruct("a", "b") -> false canConstruct("aa", "ab") -> false canConstruct("aa", "aab") -> true
[题目解析] 首先明确题意,两个字符串,第一个字符串中的字母都是从第二个字符串中取得的。可以使用hashmap,将第一个字符串读取入hashmap,key是字符,value是对应该字符的个数。
然后遍历第二个字符串,对hashmap进行操作,依次对hashmap中含有的字符个数进行--,如果个数<0,则说明map中(即第一个字符中)含有的字符,在第二个字符串中没有覆盖到。代码如下。
public boolean canConstruct(String ransomNote, String magazine) { Map charmap = new HashMap<Character,Integer>(); for(int index = 0; index < magazine.length(); index++){ char tmp = magazine.charAt(index); if(charmap.containsKey(tmp)){ int count = (int) charmap.get(tmp); count++; charmap.put(tmp, count); }else{ charmap.put(tmp, 1); } } for(int index = 0; index < ransomNote.length(); index++){ char tmp = ransomNote.charAt(index); if(charmap.containsKey(tmp)){ int count = (int) charmap.get(tmp); count--; if(count < 0) return false; charmap.put(tmp, count); }else{ return false; } } return true; }
考虑到字符串中只有小写字母,我们可以优化下代码,整体思路不变。代码如下。
public boolean canConstruct(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; }