日常刷题(242异位词)

leetccode 242

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

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

如果考虑大小写的花,可以将两字符串都转为大写或写的;当两个字符串长度不一致必定不是异位词

法一:暴力法

先把两个字符串转为字符数组,然后将两个数组排序,比较两个数组是否相同

import java.util.Arrays;
public class My {
    public static void main(String[] args) {
        String a="hello";
        String b="olleh";
        char[] str1=a.toCharArray();
        char[] str2=b.toCharArray();
        Arrays.sort(str1);
        Arrays.sort(str2);
        for (char c:str1) {
            System.out.print(c);
        }
        System.out.println();
        for (char c:str2) {
            System.out.print(c);
        }
        System.out.println("\n"+Arrays.equals(str1,str2));
    }
}

时间:排序成本 O(nlogn) 和比较两个字符串的成本 O(n)O(n) ;空间取决于排序方法

法二

      1.为了检查 t 是否是 s 的重新排列,我们可以计算两个字符串中每个字母的出现次数并进行比较。因为 S 和 T 都只包含 A-Z 的字母,所以一个简单的 26 位计数器表就足够了。
     2.为了避免两个计数器数表进行比较,可以用一个计数器表计算 s 字母的频率,用 t减少计数器表中的每个字母的计数器,然后检查计数器是否回到零。

public boolean isAnagram(String s, String t) {
    if (s.length() != t.length()) {
        return false;
    }
    int[] counter = new int[26];
    for (int i = 0; i < s.length(); i++) {
        counter[s.charAt(i) - 'a']++;
        counter[t.charAt(i) - 'a']--;
    }
    for (int count : counter) {
        if (count != 0) {
            return false;
        }
    }
    return true;
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/valid-anagram/solution/you-xiao-de-zi-mu-yi-wei-ci-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

分析下大佬代码,比如s->abcd和t->abde

新建数组counter,

 核心操作:counter[s.charAt[i]-'a']++; counter[t.charAt[i]-'a']--; 

counter[97-97]++,counter[97-97]--       结果:counter[0]的值为 0

counter[98-97]++,counter[98-97]--       结果:counter[1]的值为 0

counter[99-97]++,counter[100-97]--      结果:counter[2]的值为1,counter[3]的值为-1

counter[98-97]++,counter[101-97]--     结果:counter[1]的值为1,counter[4]的值为-1

最终 0 ,1 ,1,-1,-1,0 ,..........

public boolean isAnagram(String s, String t) {
    if (s.length() != t.length()) {
        return false;
    }
    int[] counter = new int[26];
    for (int i = 0; i < s.length(); i++) {
        counter[s.charAt(i) - 'a']++;
        counter[t.charAt(i) - 'a']--;
    }
    for (int count : counter) {
        if (count != 0) {
            return false;
        }
    }
    return true;
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/valid-anagram/solution/you-xiao-de-zi-mu-yi-wei-ci-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

或者我们可以先用计数器表计算 ss,然后用 tt 减少计数器表中的每个字母的计数器。如果在任何时候计数器低于零,我们知道 tt 包含一个不在 ss 中的额外字母,并立即返回 FALSE。

 

 

public boolean isAnagram(String s, String t) {
    if (s.length() != t.length()) {
        return false;
    }
    int[] table = new int[26];
    for (int i = 0; i < s.length(); i++) {
        table[s.charAt(i) - 'a']++;
    }
    for (int i = 0; i < t.length(); i++) {
        table[t.charAt(i) - 'a']--;
        if (table[t.charAt(i) - 'a'] < 0) {
            return false;
        }
    }
    return true;
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/valid-anagram/solution/you-xiao-de-zi-mu-yi-wei-ci-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

解答:
使用哈希表而不是固定大小的计数器。分配一个大的数组来适应整个 Unicode 字符范围,这个范围可能超过 100万。哈希表是一种更通用的解决方案,可以适应任何字符范围。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值