题目描述
给你两个字符串:
ransomNote
和magazine
,判断ransomNote
能不能由magazine
里面的字符构成。如果可以,返回
true
;否则返回false
。
magazine
中的每个字符只能在ransomNote
中使用一次。
示例1
输入:ransomNote = "a", magazine = "b"
输出:false
示例2
输入:ransomNote = "aa", magazine = "ab"
输出:false
示例3
输入:ransomNote = "aa", magazine = "aab"
输出:true
题意
判断 ransomNote 能不能由 magazine 里面的字符构成:
即只需要满足字符串 magazine 中的每个英文字母的统计次数都大于等于 ransomNote 中相同字母的统计次数即可。
思路
遍历 magazine 和 ransomNote,遍历 ransomNote + 1,遍历 magazine - 1,记为 index;
- 如果 index 小于等于0,则说明 magazine 完全抵消 ransomNote,则说明 ransomNote 可以由 magazine 里面的字符构成;
- 如果 index 存在大于0,则说明 magazine 未能完全抵消 ransomNote,则说明 ransomNote 不可以由 magazine 里面的字符构成;
代码
方法一
class Solution {
// 题意:
// 判断ransomNote能不能由magazine里面的字符构成,
// 即只需要满足字符串magazine中的每个英文字母的统计次数都大于等于ransomNote中相同字母的统计次数即可
// 思路:
// 遍历magazine和ransomNote,遍历ransomNote+1,遍历magazine-1,记为index
// 如果 index 小于等于0,则说明 magazine 完全抵消 ransomNote,则说明 ransomNote 可以由 magazine 里面的字符构成;
// 如果 index 存在大于0,则说明 magazine 未能完全抵消 ransomNote,则说明 ransomNote 不可以由 magazine 里面的字符构成;
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
char[] str1 = ransomNote.toCharArray();
char[] str2 = magazine.toCharArray();
Map<Character,Integer> map = new HashMap<Character,Integer>();
// 把ransomNote的值存进哈希表,如果存在相同,则value +1
for(char z : str1){
if(map.containsKey(z)){
map.put(z,map.get(z) + 1);
}else{
map.put(z,1);
}
}
// 通过遍历magazine字符来抵消ransomNote字符
for(char z : str2){
if(map.containsKey(z)){
map.put(z,map.get(z) - 1);
}
}
for(char z : str1){
int index = map.get(z);
if(index > 0){
// 使用index > 0遍历,确保每一次只要有一次index > 0,就说明不能由他里面的字符构成
return false;
}
/*
if(index <= 0){
// 如果使用index <= 0遍历,只要有一次index <= 0,就会返回true,不去判断后面是不是符合条件
return true;
}
*/
}
return true;
}
}
方法二
写法一
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
// 定义一个哈希映射数组
int[] cnt = new int[26];
// 遍历
for(char c : ransomNote.toCharArray()){
cnt[c - 'a']++;
}
for(char c : magazine.toCharArray()){
cnt[c - 'a']--;
}
for(int i : cnt){
if(i > 0) {
return false;
}
}
return true;
}
}
写法二
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
int[] cnt = new int[26];
// 遍历++,大于0;
for (char c : magazine.toCharArray()) {
cnt[c - 'a']++;
}
// 遍历--,如果小于0,那就 ransomNote 不可以由 magazine 里面的字符构成,返回false即可结束;
for (char c : ransomNote.toCharArray()) {
cnt[c - 'a']--;
if(cnt[c - 'a'] < 0) {
return false;
}
}
return true;
}
}
// 想要的是magazine++,即 >= 0,那就 ransomNote 可以由 magazine 里面的字符构成,返回true即可结束;
[ 注意 ]:错误写法
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
// 定义一个哈希映射数组
int[] cnt = new int[26];
// 遍历++,大于0;
for(char c : ransomNote.toCharArray()){
cnt[c - 'a']++;
}
// 遍历--,如果大于0,那就 ransomNote 不可以由 magazine 里面的字符构成,返回false即可结束;
for(char c : magazine.toCharArray()){
cnt[c - 'a']--;
// 这里错误
// 可能还没有完全遍历完,只遍历第一次,就因为 > 0,返回了flase
if(cnt[c - 'a'] > 0) {
return false;
}
}
return true;
}
}
// 想要的是magazine--,即 <= 0,那就 ransomNote 可以由 magazine 里面的字符构成,返回true即可结束;