LeetCode | 242 Valid-Anagram
分析
常见哈希结构
- 哈希表(Hash Table)
使用哈希函数将键映射到数组的索引上,从而实现键值对的快速查找。
以前利用数组的时候,数组的索引只表示序列,序列作为中介者的存在来辅助我们访问数据。借用哈希函数,索引值与目标数据本身产生了直接联系,不需要全部遍历而直接可以判断一个元素是否出现过,索引与数据等价
-
哈希集(Hash Set)
哈希集是一种不允许重复元素的集合,通常基于哈希表实现 -
哈希映射(Hash Map)
哈希映射是一种键值对集合,键是唯一的,而值可以重复
题目释义
Anagram
:
a word or phrase that is made by changing the order of the letters in another word or phrase 变位词(组)〔改变某个词或短语的字母顺序后构成的新词或短语〕
即两个字符串的每个字母字符的个数是一样的。字母字符又分为大写字母和小写字母,题目提示,s 和 t 仅包含小写字母,小写字母字符的ASCII范围为97-122>
思路
- 预设的两个字符串入参限定了小写字符这个条件。
- 注意入参的边界判断,判断null(引用为null),判断为空,即已经实例化,但是元素数量为0
- 创建一个数组容器,在本题中,HashCode的计算方式为:字符-'a',映射到数组索引下标,即字符与数组下标一一绑定
- 处理哈希冲突的方式,即一个字符串有多个重复的字符,采用累加的方式存储在容器之中
- 若两个字符串是Anagram,即放入的元素和取出的元素是一致的,即先加后减对哈希表本身像是"完全没有影响"
- 若不是,则只要出现任意一个索引不为0,即两者不是Anagram
主类
package com.github.dolphinmind.hash;
/**
* @author dolphinmind
* @ClassName ValidAnagram
* @description
* @date 2024/8/6
*/
public class ValidAnagram {
/**
* Anagram: a word or phrase that is made by changing the order of the letters in another word or phrase
* 变位词(组)〔改变某个词或短语的字母顺序后构成的新词或短语
*
* 初始判断:
* 1. 入参判断:是否为空引用,实例化是否为空字符串
* 2. 输入长度是否相等
*
* 思路:
* 1. 字母字符,26个字母,26个字母的ASCII码范围:[97, 122],固定
* 2. 任意字符减去97,得到ASCII码值,可作为数组下标,即索引与字符一一对应,即该方式的hash函数是:字符-'a'得到哈希映射
* 3. 创建26个元素的数组,用于统计s中每个字符出现的次数,字母多次出现,就相当于出现了哈希碰撞,在这里通过+1来处理哈希碰撞
* 4. 遍历t,两个字符串为Anagram,那么其每个字符出现的次数是一致的,即两个字符串等价
* 遍历后放入和取出对哈希表没有影响
* 若哈希表发生了改变,则返回false,也就表明不是Anagram
*
* 这里面其实就是在假设,两个是等价的,一个放入和取出的过程
*
* @param s
* @param t
* @return boolean
*/
public boolean isAnagram(String s, String t) {
if (s == null || t == null || s.length() == 0 || t.length() == 0) {
return false;
}
if (s.length() != t.length()) {
System.out.println("false");
}
int[] sCount = new int[26];
for (int i = 0; i < s.length(); i++) {
sCount[s.charAt(i) - 'a']++;
}
for (int i = 0; i < t.length(); i++) {
sCount[t.charAt(i) - 'a']--;
}
for (int item : sCount) {
if (item != 0) {
System.out.println("false");
return false;
}
}
System.out.println("true");
return true;
}
}