消除相邻近似相等字符

1. 题目

给你一个下标从 0 开始的字符串 word 。

一次操作中,你可以选择 word 中任意一个下标 i ,将 word[i] 修改成任意一个小写英文字母。

请你返回消除 word 中所有相邻 近似相等 字符的 最少 操作次数。

两个字符 a 和 b 如果满足 a == b 或者 a 和 b 在字母表中是相邻的,那么我们称它们是 近似相等 字符。

2. 示例

输入:word = "aaaaa"
输出:2
解释:我们将 word 变为 "acaca" ,该字符串没有相邻近似相等字符。
消除 word 中所有相邻近似相等字符最少需要 2 次操作。

示例 2:

输入:word = "abddez"
输出:2
解释:我们将 word 变为 "ybdoez" ,该字符串没有相邻近似相等字符。
消除 word 中所有相邻近似相等字符最少需要 2 次操作。

示例 3:

输入:word = "zyxyxyz"
输出:3
解释:我们将 word 变为 "zaxaxaz" ,该字符串没有相邻近似相等字符。
消除 word 中所有相邻近似相等字符最少需要 3 次操作

3. 思路

        这题是一类动态规划的题目,根据题目中所说:相邻的字符是不能有近似(即ASCII码的差值不能低于1),那么我们可以这样:定义一个数组来保存当前长度字符串的结果。然后进行一个判断:

  1. 字符串长度等于1;这里可以直接返回0
  2. 字符串长度大于1;这里就要进行下一步

判断完后咱们又有一个疑问,如果我要更新当前字符串的结果状态,该怎么转换呢?我们要知道,假设当前索引是index,那么字符串中前index-1长度的结果肯定是局部最优的,那么我们考虑的状态转移肯定包含index-1这个子状态的;那么还有其它状态吗?有!我们要知道,我们的状态数组是一个一个往里面加的,碰到相似字符也只能是当前字符上一个字符这种情况,那么此时我们就要更改这两个字符中的某一个,如果更改上一个字符,那么我们就需要考虑到倒数第2个状态:f(n-2),如果更改当前字符,那么我们就考虑上一个状态:f(n-1),因此我们的状态转移表达式为:

f(n) = min(f(n-1)+1,f(n-2)+1)

f(n-1) + 1 是 f(n-1)这个局部最优状态下更改当前字符;f(n-2) + 1 是f(n-2)这个局部最优状态下更改上一个字符。

4. 代码实现

class Solution:
    def removeAlmostEqualCharacters(self, word: str) -> int:
        result = [0,0]    # 用于保存状态
        length = len(word)    # 获取字符串长度
        # 如果长度为1,则直接返回0
        if length == 1:
            return 0
        else:
            # 从第2个字符开始遍历
            for i in range(1,length):
                # 如果当前字符和上一个字符不是近似字符,则直接使用上一次的状态,不需要更改字符
                if abs(ord(word[i]) - ord(word[i-1])) > 1:
                    result.append(result[-1])
                # 如果当前字符和上一个字符是近似字符,则需要状态转移
                else:
                    # f(n) = min(f(n-2)+1,f(n-1)+1)
                    result.append(min(
                        result[-2] + 1,    # 更改上一个字符
                        result[-1] + 1     # 更改当前字符
                    ))
            return result[-1]    # 返回最后一个字符的状态值(即为整个字符串需要更改的最小次数)

5. 结果显示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小人物₍˄·͈༝·͈˄*₎◞ ̑̑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值