Keep two pointers l and r and a hash table M = character -> count for characters in line2 that do not occur in s[l..r] .
First set l = 0 and r so that string1[l..r] contains all the characters of string2 (if possible). You do this by removing characters from M until they are empty.
Then continue by increasing r by one step at each step, and then increasing l as much as possible, while keeping M empty. The minimum over all r - l + 1 (the length of the substring s[l..r] ) is a solution.
Pythonic pseudo code:
n = len(string1) M = {}
Empty checks can be implemented in O (1) if you maintain the number of positive records when performing increment and decrement operations.
Let n be the length of string1 and m be the length of string2 .
Note that l and r only increase, so no more than O (n) increments, and therefore no more than O (n) instructions, are executed in the last outer loop.
If m implemented as an array (I assume the alphabet is a constant size), you get O (n + m) runtime, which is optimal. If the alphabet is too large, you can use a hash table for the expected output (n + m).
Execution Example:
string1 = "abbabcdbcb" string2 = "cbb" # after first loop M = { 'a': 0, 'b': 2, 'c': 1, 'd': 0 } # after second loop l = 0 r = 5 M = { 'a': -2, 'b': -1, 'c': 0, 'd': 0 } # increment l as much as possible: l = 2 r = 5 M = { 'a': -1, 'b': 0, 'c': 0, 'd': 0 } # increment r by one and then l as much as possible l = 2 r = 6 M = { 'a': -1, 'b': 0, 'c': 0, 'd': -1 } # increment r by one and then l as much as possible l = 4 r = 7 M = { 'a': 0, 'b': 0, 'c': 0, 'd': -1 } # increment r by one and then l as much as possible l = 4 r = 8 M = { 'a': 0, 'b': 0, 'c': -1, 'd': -1 } # increment r by one and then l as much as possible l = 7 r = 9 M = { 'a': 0, 'b': 0, 'c': 0, 'd': 0 }
The best solution is s [7..9].