leetcode(String)--383. 赎金信

leetcode(String)–383. 赎金信

1,题目:

在这里插入图片描述
2,思路:

方法一:排序与双指针:

  • 1.题目要求magazine中的字母是否可以构成ransomNote,且magazine中的字母不能重复使用。那么对于ransomNote中的每一个字符,都去magazine中查找是否存在(找到一个后,要从magazine中剔除)。
  • 2.用暴力查找太慢。借鉴判断字符串相等的思路,双指针分别指向两个字符串的第一个字符,依次对比,双指针一起移动。我们可以将magazine与ransomNote对应的字符数组m与r进行排序,然后使用双指针逐一对比字符。
  • 3.用指针i指向r[]的第一个字符,用j指向m的第一个字符。之后对于两个字符数组中的字符进行判断,为了防止索引越界,循环条件为while(i< r.length && j < m.length)。
  • 4.当r[i] > m[j]时,m中当前字符不能拿来构成r[i],尝试用m中的下一个字符j++
  • 5.当r[i] < m[j]时,m中当前字符已经验证过无法构成r[i]而m中当前元素及后续元素都比r[i]大,所以r[i]这个字符找不到可以构建的,答案就是return
    false
  • 6.其余情况,即r[i] == m[j],r[i]找到可以用于构建的,所以去判断下一个字符r++,注意由于magazine中字母不能重复使用,所以j++使用m中下一个字母。
  • 7.当循环结束后,如果i == r.length说明对于r中的每个字母都在m中找到对应的字母,此时可以按照题目要求构建出randomNote,返回true,否则返回false。
  • 8.双指针的遍历是线性的,但是排序是线性对数的,所以时间复杂度为O(nlog(n)+mlog(m))O(nlog(n)+mlog(m)),空间复杂度为O(m
    • n)O(m+n)。

方法二:hashmap:

解题思路
此处撰写解题思路
正如题目所示,使用hashmap统计字符出现的次数,只要赎金信里有的,杂志都有而且足够即可。
遍历一遍,时间为o(lr + lm),lr,lm分别为两者的长度
使用一个map,空间为o(lm)

首先想到java的HashMap,对字符进行计数,赎金信中的所有字符,杂志中都要有,而且,数量不能少于赎金信(key表示这个字符,value表示这个字符出现的次数)

3,代码:

方法一:排序与双指针:

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        /*
        1.题目要求magazine中的字母是否可以构成ransomNote,且magazine中的字母不能重复使用。那么对于ransomNote中的每一个字符,都去magazine中查找是否存在(找到一个后,要从magazine中剔除)。
2.用暴力查找太慢。借鉴判断字符串相等的思路,双指针分别指向两个字符串的第一个字符,依次对比,双指针一起移动。我们可以将magazine与ransomNote对应的字符数组m与r进行排序,然后使用双指针逐一对比字符。
3.用指针i指向r[]的第一个字符,用j指向m的第一个字符。之后对于两个字符数组中的字符进行判断,为了防止索引越界,循环条件为while(i < r.length && j < m.length)。
4.当r[i] > m[j]时,m中当前字符不能拿来构成r[i],尝试用m中的下一个字符j++
5.当r[i] < m[j]时,m中当前字符已经验证过无法构成r[i]而m中当前元素及后续元素都比r[i]大,所以r[i]这个字符找不到可以构建的,答案就是return false
6.其余情况,即r[i] == m[j],r[i]找到可以用于构建的,所以去判断下一个字符r++,注意由于magazine中字母不能重复使用,所以j++使用m中下一个字母。
7.当循环结束后,如果i == r.length说明对于r中的每个字母都在m中找到对应的字母,此时可以按照题目要求构建出randomNote,返回true,否则返回false。
8.双指针的遍历是线性的,但是排序是线性对数的,所以时间复杂度为O(nlog(n)+mlog(m))O(nlog(n)+mlog(m)),空间复杂度为O(m + n)O(m+n)。


        */
        char[] r = ransomNote.toCharArray();
        char[] m = magazine.toCharArray();
        Arrays.sort(r);
        Arrays.sort(m);
        int i = 0, j = 0;
        while(i < r.length && j < m.length){
            if(r[i] > m[j]) j++;//m中当前字符不能拿来构成r[i],尝试用m中的下一个字符j++
            else if (r[i] < m[j]) return false;//m中当前字符已经验证过无法构成r[i]而m中当前元素及后续元素都比r[i]大,所以r[i]这个字符找不到可以构建的,答案就是return false
            else { // 一个字母只能用一次,所以当相等时,两个指针都需要移动
                i++;
                j++;
            }
        }
        return i == r.length;//当循环结束后,如果i == r.length说明对于r中的每个字母都在m中找到对应的字母,此时可以按照题目要求构建出randomNote,返回true,否则返回false
    }


}

方法二:hashmap:

/*
解题思路
此处撰写解题思路
正如题目所示,使用hashmap统计字符出现的次数,只要赎金信里有的,杂志都有而且足够即可。
遍历一遍,时间为o(lr + lm),lr,lm分别为两者的长度
使用一个map,空间为o(lm)

*/

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        //首先想到java的HashMap,对字符进行计数,赎金信中的所有字符,杂志中都要有,而且,数量不能少于赎金信(key表示这个字符,value表示这个字符出现的次数)
        // Map<Character, Integer> ran = new HashMap<>();
        Map<Character, Integer> mag = new HashMap<>();
        for(char ch: magazine.toCharArray()){
            if(mag.containsKey(ch)) mag.put(ch, mag.get(ch)+1);//mag.get(ch)+1就是当前这个字符出现了不止一次,表示计数的功能
            else mag.put(ch, 1);//否则就是这个歌字符第一次出现,所以次数为1
        }
        for(char ch: ransomNote.toCharArray()){
            if(!mag.containsKey(ch)) 
                return false;//如果赎金信里面的字母,杂志中没有
            else if(mag.get(ch)==0) return false;//如果杂志中的字符不够
            else mag.put(ch, mag.get(ch)-1);//就是这个字符在mag中出现了,所以次数减一,因为一个已经匹配上了。
        }
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值