題目爲 給定一個字符串 s 和一些長度相同的單詞 words。找出 s 中恰好可以由 words 中所有單詞串聯形成的子串的起始位置。
注意子串要與 words 中的單詞完全匹配,中間不能有其他字符,但不需要考慮 words 中單詞串聯的順序。
第一個思路爲用一個全爲0的字符串去存儲每一個元素是否出現過,出現就變爲1。進行判斷。屬於暴力算法,代碼邏輯沒有問題,但是超時了。代碼如下
public IList<int> FindSubstring(string s, string[] words)
{
int allCount = words.Count();
List<int> res = new List<int>();
if (allCount == 0)
{
return res;
}
bool[] flagAll = new bool[allCount];
int countMax = words[0].Length;
int resFlag = 0;
int resTemp = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < allCount; i++)
{
sb.Append("0");
}
string[] rs = new string[allCount];
string equalsNums = sb.ToString();
for (int i = 0; i <= s.Length - countMax * allCount; i++)
{
words.CopyTo(rs, 0);
int wStart = i;
resTemp = i;
while (rs.ToList().Contains(s.Substring(wStart, countMax)))
{
if (equalsNums[rs.ToList().IndexOf(s.Substring(wStart, countMax))] == '0')
{
var r = rs.ToList().IndexOf(s.Substring(wStart, countMax));
equalsNums = equalsNums.Remove(r, 1);
equalsNums = equalsNums.Insert(r, "1");
wStart += countMax;
resFlag++;
rs[r] = "";
if (resFlag == allCount)
{
res.Add(resTemp);
break;
}
if (wStart + countMax > s.Length)
{
break;
}
}
else
{
i += wStart;
break;
}
}
equalsNums = sb.ToString();
resFlag = 0;
continue;
}
return res;
}
第二種思路是參考精選題解的方法,一個鍵值對,鍵存儲元素,值存儲元素出現次數。遍歷時再創建一個鍵值對,將兩個鍵值對比較。如果出現次數大於基準字符串出現次數,直接跳出。代碼如下
public IList<int> FindSubstring(string s, string[] words)
{
List<int> res = new List<int>();
int wordNum = words.Length;
if (wordNum == 0)
{
return res;
}
int wordLen = words[0].Length;
Dictionary<string, int> dic = new Dictionary<string, int>();
foreach (var item in words)
{
if (!dic.ContainsKey(item))
{
dic.Add(item, 1);
}
else
{
dic[item] += 1;
}
}
for (int i = 0; i < s.Length - wordNum * wordLen+1; i++)
{
Dictionary<string, int> dicDetail = new Dictionary<string, int>();
int num = 0;
while (num< wordNum)
{
string word = s.Substring(i+num* wordLen,wordLen);
if (dic.ContainsKey(word))
{
if (dicDetail.ContainsKey(word))
{
dicDetail[word] += 1;
}
else
{
dicDetail.Add(word, 1);
}
if (dicDetail[word] > dic[word])
{
break;
}
}
else
{
break;
}
num++;
}
if (num==wordNum)
{
res.Add(i);
}
}
return res;
}