您的位置:首页 > 编程语言 > Java开发

【LeetCode】383 Ransom Note(java)

2016-08-17 17:35 423 查看

原题

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


题目要求

题目叫做Ransom Note,勒索信,刚开始我还没理解这个题目的意思,尤其这个标题,和magazine有啥关系呢?后来仔细想想,才慢慢理解。勒索信,为了不暴露字迹,就从杂志上搜索各个需要的字母,组成单词来表达的意思。这样来说,题目也就清晰了,判断杂志上的字是否能够组成勒索信需要的那些字符。

这里需要注意的就是杂志上的字符只能被使用一次,不过不用考虑大小写的问题。

有一种最简单的理解就是对于ransomNote里每个字符出现的次数必须小于或者等于该字符在magazine出现的次数。

解法

解法一:这种解法比较简单,就是将ransomNote的字符串挨个遍历,每个字符再从magazine里遍历匹配,只是再创建了个byte数组,数组每个元素的索引表示magazine字符串的位置,元素值表示是否被校验过,0表示还未被校验过,非0就表示该位置已经被校验过。不过这种做法效率不高。

public boolean canConstruct(String ransomNote, String magazine) {
boolean ret = true;
byte[] bytes = new byte[magazine.length()];
for (int i = 0; i < ransomNote.length(); i++) {
char c = ransomNote.charAt(i);
boolean found = false;
for (int j = 0; j < magazine.length(); j++) {
if (bytes[j] == 0 && magazine.charAt(j) == c) {
bytes[j]++;
found = true;
break;
}
}
if (!found) {
ret = false;
break;
}
}

return ret;
}


解法二:将ransomNote和magazine都从小到大排序,然后对ransomNote遍历,同时在magazine中匹配,如果匹配到了,则记住此时magazine中字符的索引,便于下次操作,因为都是排序的。如果直到magazine中字符已经大于ransomNote中字符了,就说明就再也匹配不到了,则表示匹配失败。

public boolean canConstruct(String ransomNote, String magazine) {
boolean ret = true;
char[] ra = ransomNote.toCharArray();
Arrays.sort(ra);
char[] ma = magazine.toCharArray();
Arrays.sort(ma);

int index = 0;
boolean found = true;
for (int i = 0; i < ra.length && ret; i++) {
char ri = ra[i];
found = false;
for (int j = index; j < ma.length; j++) {
if (ma[j] > ri) {
ret = false;
break;
} else if (ma[j] == ri) {
index++;
found = true;
break;
} else {
index++;
}
}
if (!found) {
ret = false;
break;
}
}

return ret;
}


解法三:这是LeetCode Discuss中的最热代码,它的原理就是列出了magazine的字母表,然后算出了出现个数,然后遍历ransomNote,保证有足够的字母可用,代码非常清晰。

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;
}


原题

题目要求

解法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java leetcode string letter