满足三条件之一需改变的最少字符数
难度:
标签:
题目描述
代码结果
运行时间: 99 ms, 内存: 16.4 MB
/*
* 思路:
* 1. 使用Java Streams统计字符串a和b中每个字符的频率。
* 2. 尝试将a中的每个字符变得严格小于b中的每个字符。
* 3. 尝试将b中的每个字符变得严格小于a中的每个字符。
* 4. 尝试将a和b中的每个字符变为相同的字符。
* 5. 计算每种情况下的最小操作数,返回其中的最小值。
*/
import java.util.stream.IntStream;
public class Solution {
public int minCharacters(String a, String b) {
int[] countA = new int[26];
int[] countB = new int[26];
int lenA = a.length();
int lenB = b.length();
a.chars().forEach(c -> countA[c - 'a']++);
b.chars().forEach(c -> countB[c - 'a']++);
int res = Integer.MAX_VALUE;
// Case 3: Change a and b to the same letter
res = IntStream.range(0, 26)
.map(i -> lenA + lenB - countA[i] - countB[i])
.min()
.orElse(res);
// Case 1 and Case 2
for (int i = 0; i < 25; i++) {
countA[i + 1] += countA[i];
countB[i + 1] += countB[i];
res = Math.min(res, lenA - countA[i] + countB[i]); // Case 1
res = Math.min(res, lenB - countB[i] + countA[i]); // Case 2
}
return res;
}
}
解释
方法:
题解采用了通过计数的方式来解决问题。首先,通过Counter统计字符串a和b中每个字符的出现次数。然后,遍历从字符'a'到'z'的每个字符,对于每个字符c,计算三种操作的成本:1) 将a中所有字符变为c,b中所有字符变为c;2) 将a中所有字符变得小于c,b中所有字符变得大于c;3) 将b中所有字符变得小于c,a中所有字符变得大于c。利用累积计数(prevA和prevB),可以方便地计算在当前字符c之前或之后,字符串需要变动的字符数。最后,选取三种操作中最小的操作数作为答案。
时间复杂度:
O(m+n)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在计算最少操作数时,要初始化操作数为字符串a和b的长度之和?
▷🦆
在计算将a中所有字符变得小于c,b中所有字符变得大于c的操作成本时,为什么使用m - prevA + prevB这种计算方式?
▷🦆
在遍历字符时,为什么最后一个字符z的情况只考虑将a和b变为同一个字符,而不考虑a全小于b或b全小于a的情况?
▷🦆
题解中提到的累积计数prevA和prevB是如何帮助优化计算过程的?
▷