即尋找字符串S
的最短子字符串s
,使得s
包含字符串T
中的全部元素。
如:S
="ADOBECODEBANC"
,T
="ABC"
,知足條件的最短子字符串s
="BANC"
。spa
問題存在最優子結構性質。設f(i)
表示字符串S
的子字符串S[1:i]
中包含字符串T
中的全部元素的最短子字符串,suffix(j)
表示字符串S
的以S[j]
爲末的子字符串S[h:j]
中包含字符串T
中的全部元素的最短子字符串。以上二者若不存在知足條件的子串則爲無窮長的字符串。那麼f(i+1)=minLen(f(i),suffix(j))
。code
此題中設字符串S
長度爲n
,字符串T
長度爲m
。答案即f(n)
。狀態數n
個,狀態轉移複雜度O(1)
。而預處理字符串T
以創建T
中元素映射表只須要掃描一遍T
便可。因爲是7位ASCII碼,所以映射表佔用空間爲常量(若不是ASCII碼,可換成通用哈希表進行映射,空間複雜度爲O(m)
)。所以此題整體時間複雜度爲O(max(m,n))
。因爲解須要O(n)
的空間,空間複雜度爲O(n)
。leetcode
class Solution { static const size_t ASCIISIZE = 128; public: string minWindow(string s, string t) { int has[ASCIISIZE] = { 0 }; size_t fill = t.size(), start = s.size(), end = s.size(), min = std::numeric_limits<size_t>::max(); for (size_t i = fill; i--; ) ++has[t[i]]; for (size_t i = s.size(); i--; ) if (has[s[i]]-- > 0) if (fill == 1) { while (has[s[--end]]++ != 0) {} size_t len = end - i + 1U; if (len < min) { min = len; start = i; } } else { --fill; } return s.substr(start, min); } };
主要應用了動態規劃的思想。字符串