LeetCode——有效的字母异位词

133 阅读3分钟

「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」。

前言

大家好,我是程序猿小白 GW_gw,很高兴能和大家一起学习进步。

以下内容部分来自于网络,如有侵权,请联系我删除,本文仅用于学习交流,不用作任何商业用途。

摘要

本文主要介绍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 仅包含小写字母

  题目链接:leetcode-cn.com/leetbook/re…

【解法一】

【思路】

使用两个数组存储两个字符串每个字母出现的次数,依次进行比较。

  1. 确定特殊情况,如果长度不相同肯定不符合。
  2. 循环两个字符串,依次记录字符出现的次数。
  3. 循环对比两个数组。

【代码】

public static boolean isAnagram(String s, String t) {
    /*
    解法1:使用两个数组存储两个字符串每个字母出现的次数,依次进行比较。
     */
    //先判断两个字符串长度是否相等
    if (s.length() != t.length()) {
        return false;
    }
    int[] s1 = new int[26];
    int[] t1 = new int[26];
    int index = 0;
    for (int i = 0; i < s.length(); i++) {
        index = s.charAt(i) - 'a';
        s1[index] += 1;
    }
    for (int i = 0; i < t.length(); i++) {
        index = t.charAt(i) - 'a';
        t1[index] += 1;
    }
    for (int i = 0; i < 26; i++) {
        if (s1[i] != t1[i]) {
            return false;
        }
    }
    return true;
}

【解法二】

【思路】

利用map,存储两个字符串中每个字母出现的次数。

和第一种解法思想一致,只不过一个使用了数组,一个使用了map集合。 【代码】

public static boolean isAnagram(String s, String t) {
    /*
    解法2:利用map,存储两个字符串中每个字母出现的次数。
     */
    //先判断两个字符串长度是否相等
    if (s.length() != t.length()) {
        return false;
    }
    Map<Character, Integer> map1 = new HashMap<>();
    Map<Character, Integer> map2 = new HashMap<>();
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        map1.put(c, map1.getOrDefault(c, 0) + 1);
    }
    for (int i = 0; i < t.length(); i++) {
        char c = t.charAt(i);
        map2.put(c, map2.getOrDefault(c, 0) + 1);
    }
    for (Character c : map1.keySet()) {
        if (map2.get(c) == null || !map1.get(c).equals(map2.get(c))) {
            return false;
        }
    }
    return true;
}

【解法三】

【思路】

使用数组记录第一个字符串各个字符出现的次数,然后和第二个字符依次比较,如果有该字符串就减1,抵消掉一个。如果没有则直接返回false即可,最后也要对数组进行判断,看是否最后刚好抵消。

【代码】

public static boolean isAnagram(String s, String t) {
    /*
    解法3:计算两个字符串字符的差值
     */
    //先判断两个字符串长度是否相等
    if (s.length() != t.length()) {
        return false;
    }
    int[] count = new int[26];
    int index = 0;
    for (int i = 0; i < s.length(); i++) {
        index = s.charAt(i) - 'a';
        count[index] += 1;
    }
    for (int i = 0; i < t.length(); i++) {
        index = t.charAt(i) - 'a';
        //如果等于0,则说明另一个字符串没有该字符,如果不为0,则减一
        if (count[index] == 0) {
            return false;
        } else {
            count[index]--;
        }
    }
    for (int i = 0; i < 26; i++) {
        if (count[i] != 0) {
            return false;
        }
    }
    return true;
}

【解法四】

【思路】

先排序再比较

  1. 把字符串转化为数组
  2. 对数组排序
  3. 直接比较,如果是则排序之后完全相同。

【代码】

public static boolean isAnagram(String s, String t) {
    /*
    解法4:先排序再比较
     */
    //先判断两个字符串长度是否相等
    if (s.length() != t.length()) {
        return false;
    }
    char[] s1 = s.toCharArray();
    char[] t1 = t.toCharArray();
    Arrays.sort(s1);
    Arrays.sort(t1);
    return Arrays.equals(s1, t1);
}

【解法五】

【思路】

字符抵消法。

  1. 建立长度为26的数组,记录各个字符出现的次数。字符串s和字符串t共用一个数组来记录,如果s中存在就加1,t中存在就减1.
  2. 创建计数器count,统计两个字符串不相同的字符个数。如果最后为0则满足题意,否则不满足。
  3. 循环比较,判断该字符出现的次数,对应位置等于1说明在s中有,t中没有。
  4. 最后判断count即可。

【代码】

public static boolean isAnagram(String s, String t){
    /*
    解法5:字符抵消法。
     */
    //先判断两个字符串长度是否相等
    if (s.length() != t.length()) {
        return false;
    }
    //记录各个符出现的次数
    int[] n = new int[26];
    //记录两个字符串中不同字符的种类的数量。如果最后为0,说明两个字符串满足条件
    int count=0;
    for (int i = 0; i < s.length(); i++) {
        //对应位置等于1,说明出现了新字符
        if(++n[s.charAt(i)-'a']==1){
            count++;
        }
        //等于0,说明没有该字符了
        if(--n[t.charAt(i)-'a']==0){
            count--;
        }
    }
    return count==0;
}

小结

以上就是该题的五种解法,希望能对读者有所帮助,如有不正之处,欢迎留言指正。