【Leetcode】1737. 满足三条件之一需改变的最少字符数——1953
📝 题目
1737. 满足三条件之一需改变的最少字符数
给你两个字符串 a 和 b ,二者均由小写字母组成。一步操作中,你可以将 a 或 b 中的 任一字符 改变为 任一小写字母 。
操作的最终目标是满足下列三个条件 之一 :
a中的 每个字母 在字母表中 严格小于b中的 每个字母 。b中的 每个字母 在字母表中 严格小于a中的 每个字母 。a和b都 由 同一个 字母组成。
返回达成目标所需的 最少 操作数。
提示:
1 <= a.length, b.length <= 105a和b只由小写字母组成
🔍 思路
由于题目的目的是将两个字符串分割开来,一个字符串严格大于另外一个。
那么考虑一个分界点,如 一个字符串中所有字母都是小于等于'x',另外一个字符串里边所有字母都是严格大于'x'的(具体是'y'还是'z'到是无所谓)
上述分界点是小的字符串可以等于分界点,反之如果考虑小的严格小于分界点,大的可以等于分界点也是可以的,下列分析以前者小的可以等于分界点为准。
根据上述分析出的分界点,假定我们当前考虑的分界点是'x',那么如果计算当前分界点下的操作数?
具体的操作有两种:
- 一种是将a变为全为小于等于'x'的字符,b变为全大于'x'的字符。此时的操作数将a中大于'x'的数目+b中小于等于'x'的数目=len(a)-a中小于等于'x'的数目+b中小于等于'x'的数目
- 二是将b变为全为小于等于'x'的字符,a变为全大于'x'的字符。此时的操作数将b中大于'x'的数目+a中小于等于'x'的数目=len(b)-b中小于等于'x'的数目+a中小于等于'x'的数目
可以看到上述分析实际上一个前缀和。即小于等于'X'字符的数目
此外,我们也可以将a和b变为同一个字符,此时我们也可以借助这个分界点,将所有的字符都变为这个分界点。
因此在具体实现的过程中,我们先统计每个字符在a和b中的个数
之后计算前缀和,最后枚举分界点即可。
需要注意的是,由于字母'z'为最大的,因此这个分界点是不能为'z'的。
✍️ 代码实现
class Solution:
def minCharacters(self, a: str, b: str) -> int:
m, n = len(a), len(b)
# 统计字符串中每个字符出现的次数
ta = [0] * 26
tb = [0] * 26
# 由于a b 不一定长度相等,因此需要分别统计
for x in a:
ta[ord(x) - ord('a')] += 1
for y in b:
tb[ord(y) - ord('a')] += 1
# 计算前缀和
ca = list(accumulate(ta))
cb = list(accumulate(tb))
# 最后一个位置不能作为分界点,但是可以将所有的字符变为'z'
ans = m + n-ta[-1]-tb[-1]
for i in range(25):
ans = min(ans, m - ca[i] + cb[i], n-cb[i]+ca[i],m+n-ta[i]-tb[i])
return ans

浙公网安备 33010602011771号