力扣242. 有效的字母异位词

题目

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。

示例 1:

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

示例 2:

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

提示:

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

进阶: 如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?

详解

异或法

首先看到这个题目就想起来了刚刚写过的异或运算:力扣389.找不同-优快云博客

 所以这一题是不是也可以直接异或看结果是否为0呢?就像这样:

class Solution {
    public boolean isAnagram(String s, String t) {
        char c = 0;
        int len1 = s.length();
        int len2 = t.length();
        //记录len为len1、len2中最长的
        int len = Math.max(len1,len2);
        for (int i =0;i< len;i++){
            if (i<len1){
                c ^= s.charAt(i);
            }
            if (i<len2){
                c ^= t.charAt(i);
            }
        }
        if(c == 0){
            return true;
        }else {
            return false;
        }
    }
}

提交结果发现

解答错误

41 / 52 个通过的测试用例

原因是

解法使用了异或运算来判断两个字符串是否是字母异位词,这种方法在某些情况下可能会出错。具体来说,如果两个字符串长度相同,并且它们的字符异或结果为0,那么它们有可能是字母异位词。然而,这种判断方法不够严谨,因为不同的字符组合可能会导致相同的异或结果。

例如,考虑字符串 "ab" 和 "cc",它们的异或结果也是0,但它们并不是字母异位词。因此,这种方法存在误判的风险。

排序比较法

  1. 检查两个字符串的长度是否相同。如果不同,直接返回 false
  2. 将两个字符串的字符排序,然后比较排序后的结果是否相同。如果相同,则它们是字母异位词。
import java.util.Arrays;

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }
        
        char[] sArray = s.toCharArray();
        char[] tArray = t.toCharArray();
        
        Arrays.sort(sArray);
        Arrays.sort(tArray);
        
        return Arrays.equals(sArray, tArray);
    }
}

 Arrays.sort(sArray);此方法是排序的常用方法;

进阶

如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?

这个问题我也尝试了好久,发现上述排序比较法使用toCharArray()方法进行排序的时候,在某些特定的情况下会存在问题,特别是当字符串中包含Unicode补充字符(Supplementary Characters) 时,比如一些 emoji、罕见汉字、特殊符号等。

toCharArray 的适用场景(不会有问题)

  • 普通英文字符(如 a-z, A-Z

  • 常见的中日韩文字(位于 BMP,即基本多文种平面)

  • 一般符号和数字(如 #, 1, @ 等)

可能出问题的场景:包含 Unicode 补充字符(> U+FFFF)

例如

String str = "a😊b"; char[] chars = str.toCharArray(); System.out.println(Arrays.toString(chars));

输出为:

[a, \ud83d, \ude0a, b]

  • 😊(Unicode U+1F60A)被拆成两个 char:\ud83d\ude0a(代理对)

  • 排序后可能变成:\ude0a, a, b, \ud83d —— 导致字符显示异常甚至乱码。

 

推荐方案(安全排序方式)

int[] codePoints = str.codePoints().toArray();
Arrays.sort(codePoints);
String sorted = new String(codePoints, 0, codePoints.length);
System.out.println(sorted);

这个方案能正确识别和排序所有字符,不会破坏 emoji 等特殊字符。


总结

方法能否安全排序包含 Unicode 的字符串说明
toCharArray() + Arrays.sort()不推荐会拆开代理对,造成错误排序或乱码
codePoints() + Arrays.sort()推荐正确处理所有 Unicode 字符,包括 emoji


如果只处理英文和常见中文,用 toCharArray() 没问题;如果你要考虑 emoji、特殊符号或国际化,务必用 codePoints()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值