题目:Ransom Note
描述:
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.
Note:
You may assume that both strings contain only lowercase letters.
canConstruct(“a”, “b”) -> false
canConstruct(“aa”, “ab”) -> false
canConstruct(“aa”, “aab”) -> true
翻译:
大概意思就是传入一个任意字符串和一个其他字符串,判断第二个字符串可不可以拆分开,构成第一个任意字符串
答案:
第一版答案:(效率低,不满意,大概思路是统计这两个字符串中的每个字符的出现次数,并放到两个不同的Map中存起来,再循环遍历由任意字符串生成的Map,来看对应的key再第二个Map中是否存在,如果不存在,就肯定不能构成,如果存在,则判断次数大小,如果第二个map中的次数小,则也不能构成,思路虽然清晰,但是效率比较低。。。贴代码,稍微有点乱,讲道理,应该把其中一段抽成一个公用的方法的)
public boolean canConstruct(String ransomNote, String magazine) {
int ransomNoteSize = ransomNote.length();
int magazineSize = magazine.length();
if (magazineSize < ransomNoteSize)
return false;
Map<String, Integer> target = new HashMap<>();
Map<String, Integer> factory = new HashMap<>();
for (int i=0; i<magazineSize; i++){
if (i < ransomNoteSize) {
char c = ransomNote.charAt(i);
Integer num = target.get(c + "");
if (num == null)
target.put(ransomNote.charAt(i) + "", 1);
else
target.put(ransomNote.charAt(i) + "", ++num);
}
char c = magazine.charAt(i);
Integer num = factory.get(c + "");
if (num == null)
factory.put(magazine.charAt(i) + "", 1);
else
factory.put(magazine.charAt(i) + "", ++num);
}
Set<String> keys = target.keySet();
for (String key : keys) {
if (factory.containsKey(key)){
Integer val = target.get(key);
if (val > factory.get(key))
return false;
} else
return false;
}
return true;
}
第二个方法:由于上面方法确实效率很低,因此上网搜了一下别人的解决办法,最后写出了如下方法:
public boolean canConstruct(String ransomNote, String magazine) {
int ransomNoteSize = ransomNote.length();
int magazineSize = magazine.length();
if (magazineSize < ransomNoteSize)
return false;
int[] target = new int[26];
char a = 'a';
for (int i=0; i<magazineSize; i++)
target[magazine.charAt(i) - a]++;
for (int i=0; i<ransomNoteSize; i++) {
if (--target[ransomNote.charAt(i)- a] < 0)
return false;
}
return true;
}
上面这个方法主要是运用一个26位的数组,每个字母对应一位,和我的第一个方法类似,首先将magazine这个字符串中的每个字符出现的次数统计出来。
再循环遍历ransomNote这个字符串,遍历到一个字符串,就将target数组中字符对应的位置的数字减1,再判断这个位置的字符数量,
如果小于0,则肯定不能构成目标字符串,如果一直大于等于0,则能够构成目标字符串,最后返回true。