反转串 |豆包MarsCode AI刷题

42 阅读5分钟

小M有一个由0和1组成的字符串。他可以进行一些操作来修改字符串,并且有一个目标:将字符串的价值最小化。所谓字符串的价值,是指通过多次操作删除相邻的相同字符后剩下的字符长度。 小M每次操作可以选择修改其中的一个字符,'0'可以变为'1','1'可以变为'0'。他可以进行恰好k次修改,目的是让最终得到的字符串价值尽可能小。 你能帮助小M计算通过k次操作后,字符串的最小价值吗?

  1. 处理特殊情况:当 k 为 0 时

    • 当 k 等于 0 时,意味着不能对字符串进行修改操作,直接按照规则计算字符串的价值即可。

    • 创建一个空列表 stack,用于模拟栈结构来处理相邻相同字符的删除操作。通过一个循环遍历输入字符串 s 的每个字符,对于每个字符 char

      • 如果 stack 不为空且栈顶元素(通过 stack[-1] 获取)与当前字符 char 相等,说明出现了相邻的相同字符,按照规则将栈顶元素弹出(通过 stack.pop() 操作),相当于删除了这对相邻的相同字符。
      • 如果 stack 为空或者栈顶元素与当前字符不相等,将当前字符 char 添加到 stack 中(通过 stack.append(char) 操作)。
    • 循环结束后,stack 中剩下的字符就是经过相邻相同字符删除操作后的结果,返回 stack 的长度 len(stack),它就是此时字符串的价值。

  2. 处理 k 大于 0 的一般情况

    • 初始化变量 min_value 为 n,用于记录通过 k 次操作后字符串能达到的最小价值,初始化为 n 是因为字符串长度为 n,价值最大就是 n,后续会不断更新这个变量来找到最小值。

    • 通过一个循环遍历所有 2 ** n 种可能的修改状态(通过 state 从 0 到 1 << n - 1 进行遍历,利用位运算来表示不同的修改情况,每一位对应字符串中的一个字符位置,为 1 表示修改该位置的字符,为 0 表示不修改)。对于每一种状态 state,进行以下操作:

      • 首先构建一个临时字符串 cur_s,用于表示经过当前状态修改后的字符串。初始化一个变量 change_count 为 0,用于记录当前状态下已经进行的修改次数。通过一个内层循环遍历字符串 s 的 n 个字符(索引 i 从 0 到 n - 1),对于每个位置 i

        • 如果 state 的二进制表示中第 i 位为 1(通过 (state >> i) & 1 判断),说明要对该位置的字符进行修改,根据原字符是 '0' 还是 '1',将其修改为相反的字符(cur_s += "1" if s[i] == "0" else "0"),同时将修改次数 change_count 加 1。
        • 如果 state 的二进制表示中第 i 位为 0,直接将原字符串中的该字符添加到 cur_s 中(cur_s += s[i])。
        • 在每次修改次数加 1 后,检查 change_count 是否大于 k,如果大于 k,说明当前修改状态不符合恰好进行 k 次修改的要求,直接跳出内层循环,不再继续构建当前状态下的字符串。
      • 如果经过内层循环后,修改次数 change_count 恰好等于 k,说明当前状态是符合要求的一种修改情况,此时按照与 k = 0 时类似的方法来计算该字符串 cur_s 的价值:创建一个空列表 stack,通过一个循环遍历 cur_s 的每个字符,对于出现相邻相同字符的情况进行删除操作(通过判断栈顶元素与当前字符是否相等来决定是否弹出栈顶元素),最后得到经过处理后的 stack,其长度 len(stack) 就是当前字符串 cur_s 的价值,将这个价值与当前记录的最小价值 min_value 进行比较,使用 min 函数取两者中的较小值来更新 min_value,这样不断遍历所有可能的修改状态并比较更新,就能找到经过 k 次修改后字符串的最小价值。

  3. 返回最终结果

    • 当循环遍历完所有可能的修改状态(对于 k 大于 0 的情况)或者处理完 k = 0 的特殊情况后,min_value 变量中存储的就是通过 k 次操作后字符串的最小价值,将其返回即可。

时间复杂度方面,当 k = 0 时,遍历字符串一次来处理相邻相同字符删除的时间复杂度为 (n 为字符串长度)。当 k 大于 0 时,需要遍历所有 2 ** n 种可能的修改状态,对于每种状态构建字符串以及计算价值的操作时间复杂度大致为 (遍历字符串进行修改和处理相邻相同字符删除),所以整体时间复杂度为 ,在处理常规长度的字符串和较小的 k 值时能够通过穷举所有可能情况来计算出最小价值,但随着 n 的增大,计算量会呈指数级增长。