- 最小ウィンドウサブストリング
中文英語は
二つの文字列のソースとターゲットを考えます。ターゲットの各文字を含むソースの最小部分文字列を返します。
例
例1:
入力:ソース=「ABC」、ターゲット=「AC」
出力:「ABC」
例2:
入力:ソース=「adobecodebanc」、ターゲット=「ABC」
出力:「バンク・オブ・」
解説:「大法廷は、」ターゲット「ABC」の各文字を含むソースストリングの最小サブストリングです。
例3:
入力:ソース=「ABC」、ターゲット=「AA」
出力:「」
説明:サブストリングは、2「」が含まれています。
チャレンジ
O(N)時間
予告
なし答え、リターン「は」存在しない場合。
あなたは答えが一意であることが保証されています。
回答の必要性は、少なくともその文字の同じ番号を含むようにしながら、ターゲットは、重複した文字が含まれていてもよいです。
解決策1:
この質問は、ダブルポインタに同じアイデアを使用することですが、私はそれが容易ではなかったと思います。
- P1 0から始まる、P2は、P1、P2 ...カバー、すべてのターゲット文字間窓まで右に移動します。場合、p1は、その後、右に移動し
、ウィンドウが国境にすべての文字、そしてP2と右に移動し、カバーすることはできません。 - カウントはカウント対象の行方不明の要素内の現在のウィンドウ(P1 + 1 ... P2)を表しています。だから、数> 0と、p2が右に移動する必要があります。
- もし(MP [源[P1] ] == 0)のカウント++; すなわちソース[P1]、この時間ウィンドウは要素の内部を覆うことができなかった標的ターゲット要素です。バックP1がP2で、p2はそう融点[源[P1] = 0の場合、素子ターゲットが存在しなければならない、処理されたことに留意されたいです。
コードは以下の通りであります:
class Solution {
public:
/**
* @param source : A string
* @param target: A string
* @return: A string denote the minimum window, return "" if there is no such a string
*/
string minWindow(string &source , string &target) {
int ns = source.size();
int nt = target.size();
map<char, int> mp;
for (int i = 0; i < nt; ++i) {
mp[target[i]]++;
}
int count = mp.size();
int p1 = 0, p2 = 0;
int minLen = INT_MAX;
string minResult;
while(p1 < ns) {
while(p2 < ns && count > 0) {
mp[source[p2]]--;
if (mp[source[p2]] == 0) count--;
p2++;
if (count == 0) break;
}
if (count == 0) {
int curWinSize = p2 - p1;// + 1;
if (curWinSize < minLen) {
minLen = curWinSize;
minResult = source.substr(p1, curWinSize);
}
}
if (mp[source[p1]] == 0) count++;
mp[source[p1]]++;
p1++;
}
return minResult;
}
};