Полагаю, что нужные символы могут перемежаться ненужными, хотя в задаче и в примерах это явным образом не указано.
Словарь маленький - это хорошо. Заводим два целочисленных массива, индексированных словарём (типа гистограммы). Один Wanted - заполняем из искомой строки (например, для строки aaab он будет выглядеть как [3,1,0,0...]), второй Current. Теперь нам нужно найти минимальное окно, в котором содержатся все символы искомой строки. Пусть два индекса указывают на начало и конец текущего окна. Количество найденных полезных символов Useful := 0
Сдвигаем конец вправо.
с = S[EndIndex]
Если новый символ не из нужных (Wanted[с] = 0), ничего больше не делаем на этом шаге, сдвигаем конец дальше, иначе:
Увеличиваем соответствующий элемент Current[c]
Важный момент: увеличиваем Useful в том случае, если Current[c] не превышает Wanted[с]
Если Useful равно длине искомой строки, то двигаем начало вправо, пока это возможно (т.е. начальный символ не из нужных, или соотв. элемент Current больше Wanted)
Проверяем, минимально ли получившееся окно
Сложность линейная O(Length(A)), память - O(размер словаря)