趣味算法题

越刷越上头的趣味算法题
帅旋
关注
充电
IT宅站长,技术博主,架构师,全网id:arthinking。

哈希表计数:有效的字母异位词

发布于 2024-05-16 | 更新于 2024-08-21

题目:242. 有效的字母异位词[1]

如果您已经有思路了,或者是N刷了,可以先自己写一遍。

题目分析

题目要求判断两个字符串是否是有效的字母异位词。字母异位词是指两个字符串所含的字母相同,且各字母出现次数也相同,但是字母的排列顺序可以不同。例如,"anagram""nagaram" 是异位词,而 "rat""car" 则不是。

解题思路

要解决这个问题,有几种常见的方法:

  1. 排序比较:将两个字符串的字符进行排序,如果排序后的字符串相等,则它们是字母异位词。这种方法简单直接,但排序通常会有 O(n log n) 的时间复杂度。
  2. 哈希表计数:使用哈希表(或长度为 26 的数组)来计数每个字母的出现次数。逐个字符增加第一个字符串中的计数,然后逐个字符减少第二个字符串中的计数。最后,检查哈希表中所有计数是否为零。这种方法的时间复杂度为 O(n),空间复杂度为 O(1)。

Java解法

这里提供基于第二种方法(哈希表计数)的 Java 解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
public boolean isAnagram(String s, String t) {
// 如果两个字符串长度不同,则它们不能是异位词
if (s.length() != t.length()) {
return false;
}

// 使用HashMap来存储每个字符及其出现次数
Map<Character, Integer> map = new HashMap<>();

// 遍历第一个字符串s,并统计每个字符的出现次数
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
map.put(c, map.getOrDefault(c, 0) + 1);
}

// 遍历第二个字符串t,并递减每个字符的计数
for (int i = 0; i < t.length(); i++) {
char c = t.charAt(i);
map.put(c, map.getOrDefault(c, 0) - 1);
// 如果任何字符的计数小于0,说明t中该字符出现次数超过s
if (map.get(c) < 0) {
return false;
}
}

// 所有字符计数均匹配,返回true
return true;
}
}

时间复杂度

遍历字符串s:时间复杂度为 O(n),其中 n 是字符串 s 的长度。对于每个字符,我们进行了map.getOrDefaultmap.put操作,这两个操作的平均时间复杂度通常是 O(1),因为哈希表的平均查找和插入时间复杂度是常数。

遍历字符串t:同样,时间复杂度也是 O(n)。与遍历字符串 s 相似,对每个字符执行的操作包括检索和更新哈希表,这也是常数时间的操作。

综合起来,整个方法的时间复杂度是 O(n)。

空间复杂度

使用了一个哈希表来存储至多 n 个字符及其频次,其中 n 是字符串 s 的长度。在最坏的情况下(字符串中每个字符都不相同),这个哈希表可能需要存储 n 个键值对。

因此,空间复杂度为 O(n)。

References


  1. 242. 有效的字母异位词 ↩︎

本文作者: 帅旋

本文链接: https://www.itzhai.com/columns/algorithm/valid-anagram.html

版权声明: 版权归作者所有,未经许可不得转载,侵权必究!联系作者请加公众号。

×
IT宅

关注公众号及时获取网站内容更新。

请帅旋喝一杯咖啡

咖啡=电量,给帅旋充杯咖啡,他会满电写代码!

IT宅

关注公众号及时获取网站内容更新。