[英]Find Length of smallest substring which contains another string as subsequence
Let's say I have a string s1 = "eabegcghdefgh"
and another string s2 = "egh"
.假设我有一个字符串s1 = "eabegcghdefgh"
和另一个字符串s2 = "egh"
。
The code should return answer 4 because of the substring "efgh"
of s1
(since it's the smallest substring which contains s2
as a subsequence).由于s1
的 substring "efgh"
,代码应该返回答案4 (因为它是最小的 substring,其中包含s2
作为子序列)。
Note: There can be a couple of substrings possible, but
"efgh"
is the smallest such substring.注意:可能有几个子串,但"efgh"
是最小的,例如 substring。
In other words, find the length of smallest substring of s1
which contains all characters of another string s2
, but in order.换句话说,找到s1
的最小 substring 的长度,它包含另一个字符串s2
的所有字符,但按顺序排列。
Please note: I want to ask how to do it in O(n) time complexity.请注意:我想问一下如何在 O(n) 时间复杂度内完成。
public static String smallestWindow(String S, String T) {
if (S.equals(T)) //If S and T are equal, then simply return S.
return S;
/**
* Use sliding window.
If a substring W of S exists such that T is a subsequence of W, then a substring of S that is longer than or have the same length as W must also exist.如果 S 的 substring W 存在使得 T 是 W 的子序列,则 S 的 substring 比 W 长或与 W 具有相同长度的也必须存在。 Therefore, find such a substring of S starting from index 0 in S and index 0 in T. If the last character of T is reached, then the current index in S is the end index of the substring, and find the maximum possible start index of the substring in S. After the start index and the end index are found, the minimum window size can be updated, and store the start index and the end index as well.因此,从S中的索引0和T中的索引0开始,找到S的这样一个substring。如果到达T的最后一个字符,那么S中的当前索引就是substring的结束索引,并找到最大可能的起始索引S中的substring。找到起始索引和结束索引后,可以更新最小的window大小,同时存储起始索引和结束索引。
Then set the index in T to 0 and try to find another substring in S. Repeat the process until the end of S is reached.然后将T中的索引设置为0,尝试在S中再找一个substring,重复这个过程,直到到达S的末尾。 After all the characters in S are visited, the minimum substring length can be obtained, and return the shortest substring.访问完S中的所有字符后,可以得到最小的substring长度,返回最短的substring。
*/
int sLength = S.length(), tLength = T.length();
int start = 0, end = sLength - 1;
int sIndex = 0, tIndex = 0;
while (sIndex < sLength) {
if (S.charAt(sIndex) == T.charAt(tIndex))
tIndex++;
if (tIndex == tLength) {
int rightIndex = sIndex;
tIndex--;
while (tIndex >= 0) {
if (S.charAt(sIndex) == T.charAt(tIndex))
tIndex--;
sIndex--;
}
sIndex++;
if (rightIndex - sIndex < end - start) {
start = sIndex;
end = rightIndex;
}
tIndex = 0;
}
sIndex++;
}
int windowSize = end - start + 1;
return S.substring(start, start + windowSize);
}
This is a basic Sliding window problem often known as "Smallest window in a string containing all the characters of another string ".这是一个基本的滑动 window 问题,通常称为“包含另一个字符串的所有字符的字符串中的最小 window”。 We approach this problem by having two pointers "low" and "high" starting at the first index of the string to be searched and we increment the high pointer until all the characters of the pattern is matched and then we try to shrink the substring by incrementing the low pointer.我们通过从要搜索的字符串的第一个索引开始的两个指针“低”和“高”来解决这个问题,我们增加高指针直到模式的所有字符都匹配,然后我们尝试将 substring 缩小为增加低指针。
Here is a java snippet for the problem.这是问题的 java 片段。
public static String smallestWindow(String s, String pat){
if(s == null || s.length() == 0)return "-1";
int map[] = new int[128];
for(char k : pat.toCharArray())
map[k]++;
int count =0,start=-1,end=-1,lo=0,hi=0,min= Integer.MAX_VALUE;
for(hi = 0;hi<s.length();hi++)
{
if(map[s.charAt(hi)] >0)
count++;
map[s.charAt(hi)]--;
if(count == pat.length())
{
while(lo<hi && map[s.charAt(lo)] <0)
{ map[s.charAt(lo)]++;
lo++;
}
if(min > hi - lo +1)
{
min = hi - lo+1;
start = lo;
end = hi+1;
}
map[s.charAt(lo)]++;
lo++;
count--;
}
}
return start == -1? "-1" : s.substring(start,end);
}
i recommend you to watch this video to understand it well.我建议您观看此视频以更好地理解它。 Smallest window in a string containing all the characters of another string包含另一个字符串的所有字符的字符串中最小的 window
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.