- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
给定一个字符串 (s) 和一个整数 k,我们需要找到所有不同字符恰好出现 k 次的子字符串的数量。
示例:s = "aabbcc", k = 2
输出:6
子串 [aa, bb, cc, aabb, bbcc and aabbcc] 包含频率为 2 的不同字符。
我能想到的方法是遍历所有子串并存储当前子串的频率,并在频率等于k时增加结果。这将导致 O(n*n) 的最坏情况复杂度,其中 n 是字符串 s 的长度。
有没有更好的方法来解决这个问题?
最佳答案
我们可以在 O(n * log(size_of_alphabet))
中解决这个问题。让 f(i)
表示以第 i
th 个字符结尾的最有效的子字符串。然后:
f(i) ->
1 + f(j - 1)
where j is the rightmost index smaller
than or equal to i where s[j..i] is a
valid substring and (j - 1) is inside
the current window. Call s[j..i] the
"minimal" valid substring ending at
index i.
我们的窗口的一个不变式是,如果一个字符被看到
k + 1
次,我们将左边界移动到窗口中该字符最左边的实例。这保证了当前窗口中串联的有效子串中的任何两个子串不能有共享字符,因此保持有效串联。
k
字符
c
的第
i
实例时,最右边的索引小于或等于
s[j..i]
,其中
k
是有效子字符串,必须从窗口中计数小于
k
的所有字符的右侧开始。为了找到最右边的这样的索引,我们可能还需要在窗口中已经看到的有效相邻子串之前移动。
j
,按它们的索引优先,这样我们的
O(log(size_of_alphabet))
总是在堆的根(或堆是空的)。堆被索引,这允许我们删除
O(1)
中的特定元素。
O(1)
更新使用双端队列,因为有效的子字符串可以出现在另一个或包含现有子字符串的右侧。我们为
k
查找保留了左边界的哈希图。
for each index i in s:
let c be the character s[i]
if s[i] is the (k+1)th instance of c in the window:
move the left bound of the window
just past the leftmost instance of
c in the window, removing all
elements in the heap who's rightmost
instance we passed while updating
our window; and adding to the heap
the rightmost instance of characters
who's count has fallen below k
as we move the left bound of
the window. If the boundary moves
past the left bound of valid minimal
substrings, remove their boundaries
from the queue, and their left bound
from the hashmap.
if s[i] is the kth instance of c:
remove the previous instance of c
from the heap.
if the leftmost instance of c in the
window is to the right of the heap
root:
if (root_index + 1) is the
left bound of a valid minimal
substring in our queue:
we must be adding to the right
of all of them, so add a new
valid minimal substring, starting
at the next index after the
rightmost of those that ends
at i
otherwise:
add a new valid minimal substring,
starting at (root_index + 1)
and ending at i
otherwise:
remove the previous instance of c
in the heap and insert this one.
例如:
01234567
acbbaacc k = 2
0 a heap: (0 a)
1 c heap: (1 c) <- (0 a)
2 b heap: (2 b) <- (1 c) <- (0 a)
3 b kth instance, remove (2 b)
heap: (1 c) <- (0 a)
leftmost instance of b is to the
right of the heap root.
check root + 1 = 2, which points
to a new valid substring, add the
substring to the queue
queue: (2, 3)
result: 1 + 0 = 1
4 a kth instance, remove (0 a)
heap: (1 c)
queue: (2, 3)
result: 1
leftmost instance of a is left
of the heap root so continue
5 a (k+1)th instance, move left border
of the window to index 1
heap: (1 c)
queue: (2, 3)
result: 1
(5 a) is now the kth instance of
a and its leftmost instance is to
the right of the heap root.
check root + 1 = 2, which points
to a valid substring in the queue,
add new substring to queue
heap: (1 c)
queue: (2, 3) -> (4, 5)
result: 1 + 1 + 1 = 3
6 c kth instance, remove (1 c)
heap: empty
add new substring to queue
queue: (1) -> (2, 3) -> (4, 5) -> (6)
(for simplicity, the queue here
is not labeled; labels may be needed
for the split intervals)
result: 3 + 1 + 0 = 4
7 c (k+1)th instance, move left border
of the window to index 2, update queue
heap: empty
queue: (2, 3) -> (4, 5)
result: 4
(7 c) is now the kth instance of c
heap: empty
add new substring to queue
queue: (2, 3) -> (4, 5) -> (6, 7)
result: 4 + 1 + 2 = 7
关于string - 给定每个字符计数的字符串的子字符串数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63413388/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求提供代码的问题必须表现出对所解决问题的最低限度理解。包括尝试过的解决方案、为什么它们不起作用,以及预
为什么在 C# 中添加两个 char 结果是 int 类型? 例如,当我这样做时: var pr = 'R' + 'G' + 'B' + 'Y' + 'P'; pr 变量变为 int 类型。我希望它是
下面的代码可以编译,但 char 类型的行为与 int 类型的行为不同。 特别是 cout ::ikIsX >() ::ikIsX >() ::ikIsX >() using names
我正在寻找一个正则表达式,它可以匹配长度为 1 个或多个字符但不匹配 500 的内容。这将在 Rails 路由文件中使用,特别是用于处理异常。 路线.rb match '/500', to: 'err
对于 C 编程作业,我正在尝试编写几个头文件来检查所谓的“X 编程语言”的语法。我最近才开始,正在编写第一个头文件。这是我编写的代码: #ifndef _DeclarationsChecker_h_
为什么扩展的 ascii 字符(â、é 等)被替换为 字符? 我附上了一张图片...但我正在使用 PHP 从 MySQL 中提取数据,其中一些位置有扩展字符...我使用的是 Arial 字体。 您可以
我有一个与 R 中的断线相关的简单问题。 我正在尝试粘贴,但在获取(字符/数字)之间的断线时遇到问题。请注意,这些值包含在向量中(V1=81,V2=55,V3=25)我已经尝试过这段代码: cat(p
如何将 ANSI 字符 (char) 转换为 Unicode 字符 (wchar_t),反之亦然? 是否有用于此目的的任何跨平台源代码? 最佳答案 是的,在 中你有mbstowcs()和 wcsto
函数 fromCharCode 不适用于国际 ANSI 字符。例如,对于 ID 为 192 到 223 的俄语 ANSI (cp-1251) 字符,它返回特殊字符。如何解决这个问题? 我认为,需要将A
如果不喜欢,我想隐藏 id,但不起作用 SELECT * FROM character, character_actor WHERE character.id NOT LIKE character_a
现在这个程序成功地反转了键盘输入的单词。但是我想在我反转它之前“保存”指针中的单词,所以我可以比较两者,反转的和“原始的”,并检查它们是否是回文。我还没有太多经验,可能会出现比我知道的更多的错误,但我
Memcpy 和 memcmp 函数可以接受指针变量吗? char *p; char* q; memcpy(p,q,10); //will this work? memcmp(p,q,10); //w
恐怕我对一个相当过饱和的主题的细节有疑问,我搜索了很多,但找不到一个明确的答案来解决这个特定的明显-imho-重要的问题: 使用UTF-8将byte[]转换为String时,每个字节(8bit)都变成
我有一个奇怪的问题。我需要从 stat 命令打印输出字符串。 我已经编写了获取一些信息的代码。 import glob import os for file in glob.glob('system1
我正在使用 Java 并具有其值如下所示的字符串, String data = "vale-cx"; data = data.replaceAll("\\-", "\\-\\"); 我正在替换其中的“
String urlParameters = "login=test&password=te&ff"; 我有一个String urlParams,& - 是密码的一部分,如何使其转义,从而不被识别为分
大家好,我只想从此字符串中提取第一个字母: String str = "使 徒 行 傳 16:31 ERV-ZH"; 我只想获取这些字符: 使 徒 行 傳 并且不包括 ERV-ZH 仅数
这个问题已经有答案了: Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized point
所以, 我有一个字符**;它本质上是一个句子,带有指向该句子中每个单词的指针;即 'h''i''\0''w''o''r''l''d''\0''y''a''y''!''\0' 在这种情况下,我希望使用可
这个问题在这里已经有了答案: Using quotation marks inside quotation marks (12 个答案) 关闭 7 年前。 如何打印 " 字符? 我知道打印 % 符号
我是一名优秀的程序员,十分优秀!