1. 问题描述:
给你两个长度相等的字符串 s 和 t。每一个步骤中,你可以选择将 t 中的 任一字符 替换为 另一个字符。
返回使 t 成为 s 的字母异位词的最小步骤数。
字母异位词 指字母相同,但排列不同(也可能相同)的字符串。
示例 1:
输出:s = "bab", t = "aba"
输出:1
提示:用 'b' 替换 t 中的第一个 'a',t = "bba" 是 s 的一个字母异位词。
示例 2:
输出:s = "leetcode", t = "practice"
输出:5
提示:用合适的字符替换 t 中的 'p', 'r', 'a', 'i' 和 'c',使 t 变成 s 的字母异位词。
示例 3:
输出:s = "anagram", t = "mangaar"
输出:0
提示:"anagram" 和 "mangaar" 本身就是一组字母异位词。
示例 4:
输出:s = "xxyyzz", t = "xxyyzz"
输出:0
示例 5:
输出:s = "friend", t = "family"
输出:4
提示:
1 <= s.length <= 50000
s.length == t.length
s 和 t 只包含小写英文字母
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-number-of-steps-to-make-two-strings-anagram
2. 思路分析:
① 其实理解题目之后还是比较简单的,我们只需要统计出s与t字符串出现的字母熟练的差值即可,累计从t字符串变成s字符串需要的字母的数量,这个时候自然而然地想到使用map来进行计数,map计数与映射功能其实是很方便的,我们只需要在循环中对s字符串中出现的字母进行计数,对t字符串中出现的字母也进行计数,之后再遍历map,统计两个字母出现的差值即可,本质上考察的是map的计数
② 上面这个方法使用的时候两次map,但是实际上可以使用一次的map进行统计即可,官方提供的代码的方法二也是使用的是一次map进行计数,这个方法的话可以节省一些时间与空间
3. 代码如下:
两次map:
class Solution {
/*使用map进行计数看一下所需要的字母的数量需要多少其实理解清楚了*/
public int minSteps(String s, String t) {
Map<Character, Integer> smap = new HashMap<>();
Map<Character, Integer> tmap = new HashMap<>();
int res = 0;
for (int i = 0; i < s.length(); ++i){
char c1 = s.charAt(i);
char c2 = t.charAt(i);
smap.put(c1, smap.getOrDefault(c1, 0) + 1);
tmap.put(c2, tmap.getOrDefault(c2, 0) + 1);
}
for (Map.Entry<Character, Integer> entry : smap.entrySet()){
char c = entry.getKey();
res += Math.max(entry.getValue() - tmap.getOrDefault(c, 0), 0);
}
return res;
}
}
一次map:
class Solution {
public int minSteps(String s, String t) {
int map[] = new int[26];
for (int i = 0; i < s.length(); ++i){
char c = s.charAt(i);
/*统计s字符串中出现的次数*/
map[c - 'a']++;
}
int res = 0;
for (int i = 0; i < t.length(); ++i){
char c = t.charAt(i);
if (map[c - 'a'] == 0) ++res;
else --map[c - 'a'];
}
return res;
}
}