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);
}





相关文章
|
2月前
《LeetCode》—— 哈希
《LeetCode》—— 哈希
|
2天前
leetcode代码记录(第一个出现两次的字母
leetcode代码记录(第一个出现两次的字母
8 2
|
2天前
leetcode代码记录(有效的字母异位词
leetcode代码记录(有效的字母异位词
7 1
|
16天前
[leetcode] 705. 设计哈希集合
[leetcode] 705. 设计哈希集合
|
存储 编译器 Linux
标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”
标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”
|
25天前
【力扣】1832.判断句子是否为全字母句
【力扣】1832.判断句子是否为全字母句
|
2月前
leetcode热题100. 字母异位词分组
leetcode热题100. 字母异位词分组
18 0
|
2月前
|
算法 索引
LeetCode刷题--- 138. 复制带随机指针的链表(哈希表+迭代)
LeetCode刷题--- 138. 复制带随机指针的链表(哈希表+迭代)
|
2天前
|
算法 C++
【刷题】Leetcode 1609.奇偶树
这道题是我目前做过最难的题,虽然没有一遍做出来,但是参考大佬的代码,慢慢啃的感觉的真的很好。刷题继续!!!!!!
6 0
|
2天前
|
算法 索引
【刷题】滑动窗口精通 — Leetcode 30. 串联所有单词的子串 | Leetcode 76. 最小覆盖子串
经过这两道题目的书写,相信大家一定深刻认识到了滑动窗口的使用方法!!! 下面请大家继续刷题吧!!!
7 0

热门文章

最新文章