
【前缀和/滑动窗口】得到 K 个黑块的最少涂色次数
题目
给你一个长度为 n 下标从 0 开始的字符串 blocks ,blocks[i] 要么是 'W' 要么是 'B' ,表示第 i 块的颜色。字符 'W' 和 'B' 分别表示白色和黑色。
给你一个整数 k ,表示想要 连续 黑色块的数目。
每一次操作中,你可以选择一个白色块将它 涂成 黑色块。
请你返回至少出现 一次 连续 k 个黑色块的 最少 操作次数。
示例 1:
| |
示例 2:
| |
提示:
n == blocks.length1 <= n <= 100blocks[i]要么是'W',要么是'B'。1 <= k <= n
解题思路
所求为长度为k的区间内黑色块的最多的个数
赛时用的是前缀和维护黑色块的数目
也可以用滑动窗口
代码
| |
【模拟/动态规划】二进制字符串重新安排顺序需要的时间
题目
给你一个二进制字符串 s 。在一秒之中,所有 子字符串 "01" 同时 被替换成 "10" 。这个过程持续进行到没有 "01" 存在。
请你返回完成这个过程所需要的秒数。
示例 1:
| |
示例 2:
| |
提示:
1 <= s.length <= 1000s[i]要么是'0',要么是'1'。
解题思路
数据量小,可以用$O(n^2)$的模拟做。
此外,这题还存在$O(n)$的解法
思考时,我们可以把 01→ 10 的替换看成是 1 向左移动。每一秒,如果 1 的左面是 0,则会向左移动一步。注意连续的 1 不能同时向左移动。
从左到右遍历字符串:
如果 1 的左侧没有 0,则无需移动。
如果 11 的左侧存在 cnt(cnt > 0) 个 0,则至少需要 cnt 秒来移动;同时,如果这个 1 的左侧还存在 1,那么它至少需要比左侧那个 1 多一秒才能到达最终位置。
这是因为,当左侧的 1 刚到达最终位置的时刻,右侧的 1 一定不会移动到最终位置,而是至少与前面的 1 间隔一个 0,因为连续的 11 无法同时向左移动,从而无法同时到达最终位置。
代码
模拟
| |
动态规划
| |
【差分数组】字母移位 II
题目
给你一个小写英文字母组成的字符串 s 和一个二维整数数组 shifts ,其中 shifts[i] = [starti, endi, directioni] 。对于每个 i ,将 s 中从下标 starti 到下标 endi (两者都包含)所有字符都进行移位运算,如果 directioni = 1 将字符向后移位,如果 directioni = 0 将字符向前移位。
将一个字符 向后 移位的意思是将这个字符用字母表中 下一个 字母替换(字母表视为环绕的,所以 'z' 变成 'a')。类似的,将一个字符 向前 移位的意思是将这个字符用字母表中 前一个 字母替换(字母表是环绕的,所以 'a' 变成 'z' )。
请你返回对 s 进行所有移位操作以后得到的最终字符串。
示例 1:
| |
示例 2:
| |
提示:
1 <= s.length, shifts.length <= 5 * 10^4shifts[i].length == 30 <= starti <= endi < s.length0 <= directioni <= 1s只包含小写英文字母。
解题思路
区间修改+单点查询 可用差分数组
最后单点查询的时候再判断总共移位的情况
RE了一发是忽略了ASCII码值的范围是[0,127],而’a’=97,‘z’=122,‘z’+26>127超出了char的范围
| |
代码
| |
【倒序+线段树/并查集】删除操作后的最大子段和
题目
给你两个下标从 0 开始的整数数组 nums 和 removeQueries ,两者长度都为 n 。对于第 i 个查询,nums 中位于下标 removeQueries[i] 处的元素被删除,将 nums 分割成更小的子段。
一个 子段 是 nums 中连续 正 整数形成的序列。子段和 是子段中所有元素的和。
请你返回一个长度为 n 的整数数组 answer ,其中 answer[i]是第 i 次删除操作以后的 最大 子段和。
注意: 一个下标至多只会被删除一次。
示例 1:
| |
示例 2:
| |
提示:
n == nums.length == removeQueries.length1 <= n <= 10^51 <= nums[i] <= 10^90 <= removeQueries[i] < nremoveQueries中所有数字 互不相同 。
解题思路
倒序操作,变成从空数组开始合并
线段树维护每个区间的最大子段和,左子段和,右子段和,以及它们对应的长度
还可以用并查集
代码(线段树)
| |
偷学代码(并查集)
| |
