【前缀和/滑动窗口】得到 K 个黑块的最少涂色次数
题目
给你一个长度为 n
下标从 0 开始的字符串 blocks
,blocks[i]
要么是 'W'
要么是 'B'
,表示第 i
块的颜色。字符 'W'
和 'B'
分别表示白色和黑色。
给你一个整数 k
,表示想要 连续 黑色块的数目。
每一次操作中,你可以选择一个白色块将它 涂成 黑色块。
请你返回至少出现 一次 连续 k
个黑色块的 最少 操作次数。
示例 1:
|
|
示例 2:
|
|
提示:
n == blocks.length
1 <= n <= 100
blocks[i]
要么是'W'
,要么是'B'
。1 <= k <= n
解题思路
所求为长度为k的区间内黑色块的最多的个数
赛时用的是前缀和维护黑色块的数目
也可以用滑动窗口
代码
|
|
【模拟/动态规划】二进制字符串重新安排顺序需要的时间
题目
给你一个二进制字符串 s
。在一秒之中,所有 子字符串 "01"
同时 被替换成 "10"
。这个过程持续进行到没有 "01"
存在。
请你返回完成这个过程所需要的秒数。
示例 1:
|
|
示例 2:
|
|
提示:
1 <= s.length <= 1000
s[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^4
shifts[i].length == 3
0 <= starti <= endi < s.length
0 <= directioni <= 1
s
只包含小写英文字母。
解题思路
区间修改+单点查询 可用差分数组
最后单点查询的时候再判断总共移位的情况
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.length
1 <= n <= 10^5
1 <= nums[i] <= 10^9
0 <= removeQueries[i] < n
removeQueries
中所有数字 互不相同 。
解题思路
倒序操作,变成从空数组开始合并
线段树维护每个区间的最大子段和,左子段和,右子段和,以及它们对应的长度
还可以用并查集
代码(线段树)
|
|
偷学代码(并查集)
|
|