给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:
如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
这是我自己写的一个方法,觉得思路特别好,但是还有一个实例没有通过("bbaa", "aba")) ; 因为字符串去空,问题不大
思路:
思路:循环s次,把当前s的位置、传入子方法。子方法里判断 t 中数量是否大于0,大于零就存,然后去掉t中的字符,当t数量为0的时候,返回一个集合,将集合都存起来,集合不为空的存起来,然后找到集合里数量最短的那个就是答案。
public static string MinWindows(string s, string t)
{
if (s.Length < t.Length) { return ""; }
if (s == t) { return t; }
List<string> str = new List<string>();
for (int i = 0; i < s.Length; i++)
{
string tt = t;
if(t.Contains(s[i]))
{
string vs = diaopen(tt, i, s);
if (vs!="")
{
str.Add(vs);
}
}
}
if (str.Count == 0) return "";
if (str.Count == 1) return str[0];
int pps= str.Min(ss => ss.Length);
return str[pps-1];
}
private static string diaopen(string tt, int ii, string s)
{
//char[] tt=tts.ToCharArray();
List<char> tempstr = new List<char>();
//从第i个位置开始循环s
for (int i = ii; i < s.Length; i++)
{
if (tt.Length>0)//tt.Contains(s[i])||
{
tempstr.Add(s[i]);
//移除A
if (tt.Contains(s[i]))
{
tt = tt.Replace(s[i], ' ').Trim();
int d=tt.IndexOf(s[i]);
}
if (tt.Length<=0)
{
string xx = "";
foreach (var item in tempstr)
{
xx += item;
}
return xx;
}
}
}
return "";
}
三个月后再次做这道题,已经不记得之前做过了,但是看了之前的思路还是和现在差不多的,只不过是写法变了(超时)
public string MinWindow(string s, string t)
{
var dic = new Dictionary<char, int>();
for (int i = 0; i < t.Length; i++)
{
if (dic.ContainsKey(t[i]))
dic[t[i]]++;
else
dic[t[i]] = 1;
}
List<string> resList = new List<string>();
for (int i = 0; i < s.Length; i++)
{
if (dic.ContainsKey(s[i]))
{
string temp = GetMinLen(dic, s);
resList.Add(temp);
}
}
return resList.Min();
}
private string GetMinLen(Dictionary<char, int> dic, string s)
{
string str = "";
int count = 0;
foreach (var item in s)
{
while (dic.Count != 0||count<s.Length)
{
if (dic.ContainsKey(item))
{
dic[item]--;
str += item;
break;
}
}
}
return str;
}
参考一个答案:
public class Solution {
public string MinWindow(string s, string t) {
if (s == null || s.Length == 0 ||
t == null || t.Length == 0)
{
return "";
}
var bank = new int[256];
int left = 0;
int right = 0;
int count = 0;
int min = Int32.MaxValue;
string minString = "";
var pLength = t.Length;
var length = s.Length;
for (int i = 0; i < pLength; i++)
{
bank[t[i]]++;
}
while (right < length)
{
var rightChar = s[right];
right++; // always advance one to next iteration
if (bank[rightChar] > 0)
{
count++;
}
bank[rightChar]--; // always decrement one no matter char is in pattern t or not
// move left pointer until missing one char from string t
while (count == pLength)
{
var size = right - left;
if (min > size)
{
min = size;
minString = s.Substring(left, right - left);
}
// shift our window
var leftChar = s[left];
left++; // always move left pointer
bank[leftChar]++; // always increment one no matter char is in pattern t or not
if (bank[leftChar] > 0) // that means left char is one of chars in pattern, also count as one
{
count--;
}
}
}
return minString;
}
}