leetcode【哈希表—简单】242.有效的字母异位词

简介: leetcode【哈希表—简单】242.有效的字母异位词

题目


题目来源leetcode


leetcode地址:242. 有效的字母异位词,难度:简单。


题目描述(摘自leetcode):


给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false
提示:
1 <= s.length, t.length <= 5 * 104
s 和 t 仅包含小写字母


本地调试代码:


class Solution {
    public boolean isAnagram(String s, String t) {
    ...
    }
  public static void main(String[] args) {
        String s = "anagram";
        String t = "anggram";
        System.out.println(new Solution().isAnagram(s,t));
    }
}



题解


NO1:暴力法(O(n2),超时)


思路:


代码:


public boolean isAnagram(String s, String t) {
    //字符串长度不相等、为0情况直接返回
    if(s == null || t == null || s.length() != t.length() || s.length() == 0){
        return false;
    }
    for (int i = 0; i < s.length(); i++) {
        int sNum = 0;
        char sChar = s.charAt(i);
        //s字符串获取当前字符的相同个数
        for (int j = 0; j < s.length(); j++) {
            if(sChar == s.charAt(j)){
                sNum++;
            }
        }
        //t字符串统计sChar的个数
        int tNum = 0;
        for (int j = 0; j < t.length(); j++) {
            if(sChar == t.charAt(j)){
                tNum++;
            }
        }
        if(tNum !=sNum){
            return false;
        }
    }
    return true;
}



NO2:哈希法(重点,O(n))


思路:根据提示s 和 t 仅包含小写字母,所以我们可以直接定义一个大小为26的int数组默认索引值都为0,对应下标0-25存放'a'-'z'的重复次数,之后遍历s、t来进行统计,最终可根据数组中的值是否相等或为0来确定是否为有效的字母异位词。


代码:下面是进行修改了三次,思路都是一致的


//首次看思路自己写代码
public boolean isAnagram(String s, String t) {
    if(s == null || t == null || s.length()!=t.length() || s.length() == 0){
        return false;
    }
    //设置两个数组来进行分别记录对应的字符串字符的数量
    int[] sArr = new int[26];
    int[] tArr = new int[26];
    //遍历一遍s
    for (int i = 0; i < s.length(); i++) {
        sArr[s.charAt(i)-'a']++;
        tArr[t.charAt(i)-'a']++;
    }
    for (int i = 0; i < 26; i++) {
        if(sArr[i] != tArr[i]){
            return false;
        }
    }
    return true;
}
//优化一:两个数组=>一个数组
public boolean isAnagram(String s, String t) {
    if(s == null || t == null || s.length()!=t.length() || s.length() == 0){
        return false;
    }
    //使用一个数组来进行存储
    int[] recordsNumsArr = new int[26];
    //长度一致,我们分别来进行+、-操作对数组的某个索引值
    for (int i = 0; i < s.length(); i++) {
        recordsNumsArr[s.charAt(i)-'a']++;
        recordsNumsArr[t.charAt(i)-'a']--;
    }
    //来对记录字符数的数组进行遍历,一旦某个数组索引值!=0说明不有效
    for (int i = 0; i < 26; i++) {
        if(recordsNumsArr[i] != 0){
            return false;
        }
    }
    return true;
}
//优化二:添加提前结束操作
public boolean isAnagram(String s, String t) {
    if(s == null || t == null || s.length()!=t.length() || s.length() == 0){
        return false;
    }
    //使用一个数组来进行存储
    int[] recordsNumsArr = new int[26];
    for (int i = 0; i < s.length(); i++) {
        recordsNumsArr[s.charAt(i)-'a']++;
    }
    for (int i = 0; i < t.length(); i++) {
        recordsNumsArr[t.charAt(i)-'a']--;
        //提前结束:一旦在t中的某个字符相同数量>s中的
        if(recordsNumsArr[t.charAt(i)-'a'] < 0){
            return false;
        }
    }
    //来对记录字符数的数组进行遍历,一旦某个数组索引值!=0说明不有效
    for (int i = 0; i < 26; i++) {
        if(recordsNumsArr[i] != 0){
            return false;
        }
    }
    return true;
}







用Java执行的话大多数都是需要4ms,我还在想为啥只击败了45%,之后使用c语言的同样逻辑代码测了下过0ms,直接击败100%。


bool isAnagram(char *s, char *t)
{
  int i, x[26] = { 0 }, y[26] = { 0 };
  for (i = 0; s[i] != '\0'; i++)  x[s[i] - 'a']++;  //建立 s 的字符表 x
  for (i = 0; t[i] != '\0'; i++)  y[t[i] - 'a']++;  //建立 t 的字符表 y
  for (i = 0; i < 26; i++)        //比较两字符表是否相同
  if (x[i] != y[i]) return false;
  return true;          //种类、个数均相同
}




NO3:借助Java的API来解决


//方式一:字符数组排序比对
public boolean isAnagram(String s, String t) {
    if(s == null || t == null || s.length()!=t.length() || s.length() == 0){
        return false;
    }
    //思路:字符串s、t转成字符数组,分别进行排序,之后使用Arrays工具类进行比较
    char[] sArr = s.toCharArray();
    char[] tArr = t.toCharArray();
    Arrays.sort(sArr);
    Arrays.sort(tArr);
    return Arrays.equals(sArr,tArr);
}
//方式二:利用map集合解决
public boolean isAnagram(String s, String t) {
    if(s == null || t == null || s.length()!=t.length() || s.length() == 0){
        return false;
    }
    Map<Character,Integer> map = new HashMap<>(s.length());
    //遍历字符数组s,以key、value进行存储,key设置为字符,value则表示指定的数字
    for(char ch : s.toCharArray()){
        map.put(ch,map.getOrDefault(ch,0)+1);
    }
    //遍历字符数组t
    for(char ch : t.toCharArray()){
        Integer num = map.get(ch);
        //为null表示没有该数
        if(num == null){
            return false;
        }else if(num>1){
            map.put(ch,num-1);
        }else{ //num<=1情况,数量-1即可0,此时我们直接移除即可
            map.remove(ch);
        }
    }
    return map.isEmpty();
}
//方式三:使用strean
public boolean isAnagram(String s, String t) {
    if(s == null || t == null || s.length()!=t.length() || s.length() == 0){
        return false;
    }
    int[] numArr = new int[26];
    //这里不使用stream是因为若是转为数组还有个copy过程
    s.chars().forEach(ch->numArr[ch-'a']++);
    t.chars().forEach(ch->numArr[ch-'a']--);
    //直接对数组进行stream流操作
    return Arrays.stream(numArr).allMatch(ch->ch == 0);
}





相关文章
|
5月前
|
存储 算法
LeetCode第49题字母异位词分组
LeetCode第49题"字母异位词分组"的解题方法,通过将每个字符串的字符排序后作为键存储在HashMap中,有效地将所有字母异位词分组。
LeetCode第49题字母异位词分组
|
7月前
|
索引
力扣随机一题 6/26 哈希表 数组 思维
力扣随机一题 6/26 哈希表 数组 思维
43 0
|
3月前
|
存储
Leetcode第49题(字母异位词分组)
LeetCode第49题要求将字符串数组中的字母异位词分组,可以通过将每个字符串排序后作为键存入哈希表,最后将哈希表中的值添加到结果列表中来实现。
22 1
|
3月前
|
算法
Leetcode第十七题(电话号码的字母组合)
这篇文章介绍了如何使用深度优先搜索(DFS)算法来解决LeetCode第17题——电话号码的字母组合问题,通过递归方法生成所有可能的字母组合。
27 0
Leetcode第十七题(电话号码的字母组合)
|
3月前
|
索引
【LeetCode 11】242.有效的字母异位词
【LeetCode 11】242.有效的字母异位词
19 0
【LeetCode 11】242.有效的字母异位词
|
3月前
|
算法
【LeetCode 52】17.电话号码的字母组合
【LeetCode 52】17.电话号码的字母组合
42 0
|
5月前
|
算法
LeetCode第17题电话号码的字母组合
该文章介绍了 LeetCode 第 17 题电话号码的字母组合的解法,通过分析得出可使用递归和回溯的思想解决,避免循环穷举的高循环次数,并给出了具体的编码实现,同时总结了该题较难理解,需要了解递归的本质,当嵌套循环层次多时可考虑递归。
LeetCode第17题电话号码的字母组合
|
7月前
力扣随机一题 哈希表 排序 数组
力扣随机一题 哈希表 排序 数组
44 1
|
4月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
5月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
130 2