给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:
输入: s = “rat”, t = “car”
输出: false
说明:
你可以假设字符串只包含小写字母。
四步刷题法:
(1)clarification (和面试官过一遍题目)
(2)possible solution--》optional(time & space) (找到能想到的最优解法)
(3)code (写代码)
(4)test cases (测试样例)
分析:
(1)暴力: 先把两个字符串都 sort 一遍,再把两个字符串进行比较是否相等(O(NlogN))
(2)hash表:用map进行存储每个字母出现的次数
可做优化处理:第一个字符串统计出现频次,第二个字符串碰到相同字母进行减一;
第一个单词进行加一,第二个单词碰到了则进行减一,最后判断map是否为空)
方法一: 使用map集合
思路就是遍历2个char数组,对map进行put,get操作。最后返回map.size() == 0。
import java.util.HashMap;
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public boolean isAnagram(String s, String t) {
//map用来存储字符串中出现的字符
HashMap<Character,Integer> map = new HashMap<Character, Integer>();
//遍历第一个字符串,把出现过的字符加入map中,并记录出现的次数
for (int i = 0; i < s.length(); i++) {
map.put(s.charAt(i),map.getOrDefault(s.charAt(i), 0) + 1);
}
//遍历第二个字符串,如果出现和第一个字符串一样的字符,则把对应的出现的次数-1
for (int i = 0; i < t.length(); i++) {
// 当map中存在key时,输出对应的value
// 当map中不存在key时,输出defaultValue:0
Integer orDefault = map.getOrDefault(t.charAt(i), 0);
//如果t字符串中出现了在s字符串中没有出现的字符,一开始就会把默认值设为0,如果为0直接返回
if (orDefault == 0){
return false;
}
if (orDefault > 0){
orDefault--;
map.put(t.charAt(i),orDefault);
}
//如果出现过在第一个字符串中的字符次数减为0了,则将键值对移除
if (orDefault == 0){
map.remove(t.charAt(i));
}
}
return map.size() == 0;//如果map的长度为0 则表示两个字符串出现的字符次数一样,返回true
}
}
//leetcode submit region end(Prohibit modification and deletion)
方法二: 暴力法,使用排序比较
先把两个字符串都 sort 一遍,再把两个字符串进行比较是否相等(O(NlogN))
思路:数组equals比较
说明: 字符串都是小写字母组成,使用临时数组存在每个字符出现次数。
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()){
return false;
}
//把字符串改成字符数组
char[] sChars = s.toCharArray();
char[] tChars = t.toCharArray();
Arrays.sort(sChars);
Arrays.sort(tChars);
return Arrays.equals(sChars,tChars);
}