本文涉及的基础知识点
C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频
LeetCode1737. 满足三条件之一需改变的最少字符数
给你两个字符串 a 和 b ,二者均由小写字母组成。一步操作中,你可以将 a 或 b 中的 任一字符 改变为 任一小写字母 。
操作的最终目标是满足下列三个条件 之一 :
a 中的 每个字母 在字母表中 严格小于 b 中的 每个字母 。
b 中的 每个字母 在字母表中 严格小于 a 中的 每个字母 。
a 和 b 都 由 同一个 字母组成。
返回达成目标所需的 最少 操作数。
示例 1:
输入:a = “aba”, b = “caa”
输出:2
解释:满足每个条件的最佳方案分别是:
- 将 b 变为 “ccc”,2 次操作,满足 a 中的每个字母都小于 b 中的每个字母;
- 将 a 变为 “bbb” 并将 b 变为 “aaa”,3 次操作,满足 b 中的每个字母都小于 a 中的每个字母;
- 将 a 变为 “aaa” 并将 b 变为 “aaa”,2 次操作,满足 a 和 b 由同一个字母组成。
最佳的方案只需要 2 次操作(满足条件 1 或者条件 3)。
示例 2:
输入:a = “dabadd”, b = “cda”
输出:3
解释:满足条件 1 的最佳方案是将 b 变为 “eee” 。
提示:
1 <= a.length, b.length <= 105
a 和 b 只由小写字母组成
前缀和
n1 = a.length,n2=b.lenght
方式一:从’a’到’y’枚举a中的最大字符ch。
将a中大于ch的字符变成’a’,将b中小于等于ch的字符变成’z’。
方式二:类似方式一枚举b。
方式三:cnta[i]记录 a中’a’+i的数量。cntb[i]记录b中’a’+i的数量。 cnt=ctna+ctnb。
方式二的结果:n1+n2 - max(cnt)
代码
核心代码
class Solution {
public:
int minCharacters(string a, string b) {
const int N1 = a.length();
const int N2 = b.length();
int cnta[26] = { 0 }, cntb[26] = { 0 }, cnt[26] = { 0 };
for (const auto& ch : a) {
cnta[ch - 'a']++;
cnt[ch - 'a']++;
}
for (const auto& ch : b) {
cntb[ch - 'a']++;
cnt[ch - 'a']++;
}
int ret = INT_MAX;
auto Fun1 = [&](int* cnta, int* cntb,const int N) {
int cnt1 = 0, cnt2 = 0;
for (int i = 0; i < 25; i++) {
cnt1 += cnta[i];
cnt2 += cntb[i];
ret = min(ret, N - cnt1 + cnt2);//方式一
}
};
Fun1(cnta, cntb,N1);
Fun1(cntb, cnta,N2);
ret = min(ret, N1+N2 - *std::max_element(cnt,cnt+26));
return ret;
}
};
单元测试
string a,b;
TEST_METHOD(TestMethod1)
{
a = "dee", b = "a";
auto res = Solution().minCharacters(a, b);
AssertEx(0, res);
}
TEST_METHOD(TestMethod11)
{
a = "aba", b = "caa";
auto res = Solution().minCharacters(a, b);
AssertEx(2, res);
}
TEST_METHOD(TestMethod12)
{
a = "dabadd", b = "cda";
auto res = Solution().minCharacters(a, b);
AssertEx(3, res);
}