Java每日一题——>剑指 Offer II 032. 有效的变位词

Posted stormzhuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java每日一题——>剑指 Offer II 032. 有效的变位词相关的知识,希望对你有一定的参考价值。

题目

这是LeetCode上的 [032,有效的变位词],难度为 [简单]

给定两个字符串 s 和 t ,编写一个函数来判断它们是不是一组变位词(字母异位词)。

注意:若 s 和 t 中每个字符出现的次数都相同且字符顺序不完全相同,则称 s 和 t 互为变位词(字母异位词)。

示例 1:

输入: s = "anagram", t = "nagaram"
输出: true

示例 2:

输入: s = "rat", t = "car"
输出: false

示例 3:

输入: s = "a", t = "a"
输出: false

提示:

  • 1 <= s.length, t.length <= 5 * 104
  • s and t 仅包含小写字母

题解1(数组)

根据题意,需要算出两个字符串中的每个字符出现的次数,然后比较它们同个字符出现的次数是否相等,若不相等,则不是是变位词

如果只考虑字符串中字符只包含英文小写字符的情况,可以声明一个容量为26的频次数组来存放字符串中每个字符出现的次数,索引为0的位置存放a出现的次数

那怎么算出每个字符需要放在那个索引呢?由于每个字符都有对应的unicode编码,对应int整数,因此可以把每个字符减去字符a就可以得到它在数组中得索引,例如当字符为a时,则a - a = 0,即索引为0,存放在数组的第一个位置

代码实现

class Solution 
   public boolean isAnagram(String str1, String str2) 
        /* 若字符串长度不相等,则不是变位词(变位词是顺序不同,但字符和每个字符出现的都相同
        * 若字符串相等,则不是变位词*/
        if (str1.length() != str2.length() || str1.equals(str2)) 
            return false;
        
        // 创建一个频次数组,存放每个字符出现的次数
        int[] counts = new int[26];
        // 字符串转化位char数组
        char[] chars1 = str1.toCharArray();
        char[] chars2 = str2.toCharArray();
        // 遍历第一个char型数组,统计每个字符出现的次数
        for (char ch : chars1) 
            counts[ch - 'a']++;
        
        // 遍历第二个char型数组,
        for (char ch : chars2) 
            /* 若频次数组中的当前字符出现的次数为0,
            则说明第一个字符串不包含第二个字符串的当前字符,则不是变位词*/
            if (counts[ch - 'a'] == 0) 
                return false;
            
            // 若频次数组中当前字符出现的次数不为0,则把当前字符的次数减1
            counts[ch - 'a']--;
        
        return true;
    

复杂度分析


假设字符串的长度为n

时间复杂度:

需要遍历两个字符串,故时间复杂度为O(n) + O(n) = 2O(n) = O(n)

空间复杂度:

由于频次数组是容量是固定的,故空间复杂度为O(1)

题解2(哈希表)

如果字符串中字符不只包含英文字符时,例如包含中文,日文等其他字符,则可以使用java中哈希表HashMap作为频次数组,HashMap会随着字符串中不同字符的数目增多而扩容

代码实现

class Solution 
   public boolean isAnagram(String str1, String str2) 
     if (str1.length() != str2.length() || str1.equals(str2)) 
            return false;
        
        // 创建哈希表作为频次数组
        HashMap<Character, Integer> counts = new HashMap<>();
        for (char ch : str1.toCharArray()) 
            /* 记录当前字符出现的次数,
            getOrDefault是若哈希表(频次数组)不存在当前字符,则取默认值0作为当前字符的出现的次数*/
            counts.put(ch, counts.getOrDefault(ch, 0) + 1);
        
        for (char ch : str2.toCharArray()) 
            /* 若哈希表(频次数组)不包含当前字符,则不是变位词组
            * 若哈希表(频次数组)当前字符出现的次数为0,
            * 则说明第一个字符串中不包含第二个字符串的当前字符,即不是变位词组*/
            if (!counts.containsKey(ch) || counts.get(ch) == 0) 
                return false;
            
            // 哈希表(频次数组)当前字符出现的次数大于0,则把当前字符出现次数减一
            counts.put(ch, counts.get(ch) - 1);
        
        return true;
    

复杂度分析

假设两个字符串的长度为n

时间复杂度

需要链表两个字符串,故时间复杂度为O(n)

空间复杂度

哈希表会随着字符串中不同字符个数的增多而扩容,假设不同字符的个数为K,则空间复杂度为O(k)

以上是关于Java每日一题——>剑指 Offer II 032. 有效的变位词的主要内容,如果未能解决你的问题,请参考以下文章

Java每日一题——>剑指 Offer II 035. 最小时间差(三解,蛮力,排序,哈希)

Java每日一题——> 剑指 Offer II 028. 展平多级双向链表

Java每日一题——>剑指 Offer II 027. 回文链表

Java每日一题——>剑指 Offer II 030. 插入删除和随机访问都是 O 的容器

Java每日一题——>剑指 Offer II 034. 外星语言是否排序

Java每日一题——>剑指 Offer II 034. 外星语言是否排序