在字符串S中查找最小长度子字符串,其中包含来自字符串T的所有字符串,使用O(n)中的哈希表

时间:2016-10-14 12:53:54

标签: string algorithm hash hashtable

我知道这个问题已被不止一次提出过。我怀疑是不是找到了这个问题的解决方案,而是正确的复杂性。 我在这里读到了答案:

Minimum window width in string x that contains all characters in string y
在这个解决方案中,提出的复杂性是O(n)使用哈希表。现在直到在哈希表中映射字符串T的字符是好的,但是当从哈希表中找到最小和最大元素时,几乎在每个答案中,我读了一个使用的链表,他们写道,更新链表的复杂性是O(1)。这就是怀疑的地方。

请考虑以下示例:

S:abcbae

T:ABC

最初t [“a”],t [“b”]和t [“c”]将为-1,经过3次传递后,值分别为0,1,2(在哈希表中)和双链表将包含 [(a,0) - (b,1) - (c,2)] 元素。

现在字符串S中的第四个字符是 b ,所以在为DLL中的 b 添加索引的新值之前,我需要删除它的前一个实例,我将为此必须遍历DLL。

我的问题是,为什么更新DLL的解决方案是O(1),是不是O(n),这会导致O(n ^ 2)的总复杂度?

[O(n)用于遍历字符串S,然后O(n)用于更新DLL]

如果我错了,请纠正我。

1 个答案:

答案 0 :(得分:1)

所描述的数据结构是一个双向链表,使用answer中的示例可视化如下:

HEAD <=> ('c', 0) <=> ('b', 3) <=> ('a', 5) <=> TAIL

与数组相结合,可视化如下:

      'a'      |      'b'      |      'c'
 {5, &list[2]} | {3, &list[1]} | {0, &list[0]}

(注意重复信息)

在所述算法期间的任何时候,都需要进行以下操作:

  1. 在数组中插入元素
  2. 在列表中插入元素
  3. 查找给定字符的索引值
  4. 从列表中删除节点
  5. #1的时间复杂度是O(1)(平凡),而#2也是O(1),因为我们选择了双链表。

    由于我们选择了数组,#3的时间复杂度也是O(1)。对于支持散列表的地图,它仍然是O(1)。

    #4的时间复杂度为O(1),因为我们的数组包含指向列表中每个节点的指针,并且每个字符在列表中只有一个节点,因此删除也很简单。

    重要的是要注意(并理解)在所提算法的任何迭代中,最小窗口不能大于最后一步(为什么?证明它),因此我们只需要< em>字符串Y中的每个字符最多一个节点(或问题中的T)。

    希望这有帮助。