LeetCode Online Judge 题目C# 练习 - Minimum Window Substring

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC".

Note:
If there is no such window in S that covers all characters in T, return the empty string "".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

 1         public static string MinimumWindowSubstring(string S, string T)
 2         {
 3             Dictionary<char, Queue<int>> tbl = new Dictionary<char, Queue<int>>();
 4             int ct = 0; // counter to find the first full set
 5             int lowest = 0;  // lowest index of current set
 6 
 7             for (int i = 0; i < T.Length; ++i) {
 8                 if (!tbl.ContainsKey(T[i]))
 9                     tbl[T[i]] = new Queue<int>();
10                 tbl[T[i]].Enqueue(-1);
11             }
12 
13             int minlen = S.Length, start = -1;  // min length and start position
14 
15             Queue<int> p;
16             for (int i = 0; i < S.Length; ++i) 
17                 if (tbl.ContainsKey(S[i]))
18                 {
19                     p = tbl[S[i]];
20                     if (p.Peek()  == -1) 
21                         ++ct;
22                     p.Enqueue(i);
23                     p.Dequeue();
24                     if (ct == T.Length && (minlen == S.Length || S[i] == S[lowest])) 
25                     {
26                         lowest = S.Length;
27                         foreach (var item in tbl)
28                         {
29                             if (item.Value.Peek() < lowest)
30                                 lowest = item.Value.Peek();
31                         }
32                         int len = i - lowest + 1;
33                         if (len < minlen || len == S.Length)
34                         {
35                             start = lowest;
36                             minlen = len;            
37                         }
38                     }
39                 }
40 
41             if (start == -1) 
42                 return "";
43             else 
44                 return S.Substring(start, minlen);
45         }

代码分析:

  O(m*n)。代码中的Queue<int>是用来应付 T 中有duplicate, 比如说“ABAC"。 如果问题中说明了 T 中的字符都是unique的话,我们用Dictionary<char, int>,其中int用来存放最近的一个index就可以了。

  例子:S= "ADOBECODEBANC", T = "ABC" 

A -1, 0
B -1, 3
C -1, 5

  此时,ct = 3, i = 5, 在map中找出最小的index = 0, 计算最短长度minlen = 5 - 0 + 1 = 6, start = 0, lowest = 0

A
B 3, 9
C 5

  B != 之前 lowest 的字符 'A' 继续。。。

A 0, 10
B 3, 9
C 5

  此时,S[i] == S[lowest], 在map中找出最小的index = 5, 计算最短长度minlen = 10 - 5 + 1 = 6, start = 5, lowest = 5

A 10
B 9
C 5,12

  此时,S[i] == S[lowest], 在map中找出最小的index = 9, 计算最短长度minlen = 12 - 9 + 1 = 4, start = 9, lowest = 9

  S.Substring(start, minlen) = "BANC";

posted @ 2012-09-29 03:53  ETCOW  阅读(356)  评论(0编辑  收藏  举报