📜  进行最少的删除,以使字符串由0s的子字符串和随后的1s的子字符串串联而成(1)

📅  最后修改于: 2023-12-03 15:12:20.160000             🧑  作者: Mango

题目介绍

这道题目要求我们进行最少的删除操作,使得给定的字符串由0s的子字符串和随后的1s的子字符串串联而成。比如说,对于字符串 "101101",我们可以将它变为 "101" 或者 "11",其中都只需要进行一次删除操作,满足要求。

解题思路

我们可以先遍历一遍字符串,记录下其中连续的 0 和 1 的个数。假设得到了一个长度为 n 的数组 nums,其中 n 表示字符串中连续的 0 和 1 的组数,nums[i] 表示第 i 组 0 或 1 的个数。比如说,对于字符串 "101101",得到的数组为:

nums = [1, 1, 2, 1, 1]

然后我们可以分别考虑两种情况:

1.如果字符串的第一个字符为 0,那么我们需要删除 nums[0] 这个元素,因为它不能作为一个 1s 的子字符串的开头。同样的,如果字符串的最后一个字符为 1,那么我们需要删除 nums[-1] 这个元素,因为它不能作为一个 0s 的子字符串的结尾。

2.对于其它位置的元素,我们需要判断它前后的两个元素是否相同,如果不同,我们就要删除其中一个元素。比如说,对于数组 [1, 2, 2, 1],我们可以将它变为 [1, 2, 1],也可以将它变为 [2, 2],都只需要进行一次删除操作。

最终,我们删除的操作次数就是所有需要删除的元素个数之和。在上面的例子中,需要进行的删除操作次数为 2。

代码实现

def min_deletions(s: str) -> int:
    nums = []
    cnt = 1
    for i in range(1, len(s)):
        if s[i] == s[i-1]:
            cnt += 1
        else:
            nums.append(cnt)
            cnt = 1
    nums.append(cnt)
    ans = 0
    if s[0] == '0':
        ans += 1
        nums.pop(0)
    if s[-1] == '1':
        ans += 1
        nums.pop(-1)
    nums.sort(reverse=True)
    for i in range(1, len(nums)):
        while nums[i] >= nums[i-1] and nums[i] > 0:
            nums[i] -= 1
            ans += 1
    return ans

复杂度分析

时间复杂度:$O(nlogn)$。排序的时间复杂度为 $O(nlogn)$,其它操作的时间复杂度都是 $O(n)$,因此总的时间复杂度为 $O(nlogn)$。

空间复杂度:$O(n)$。我们需要存储一个长度为 n 的数组,空间复杂度为 $O(n)$。