1. 题⽬链接:30.串联所有单词的⼦串
2. 题⽬描述:
3. 解法(滑动窗⼝+哈希表):
算法思路:
如果我们把每⼀个单词看成⼀个⼀个字⺟,问题就变成了找到「字符串中所有的字⺟异位词」。⽆ ⾮就是之前处理的对象是⼀个⼀个的字符,我们这⾥处理的对象是⼀个⼀个的单词。
C++算法代码:
class Solution
{
public:
vector<int> findSubstring(string s, vector<string>& words)
{
//记录words字符串中所有单词的出现次数
unordered_map<string, int>mubiao;
for (int i = 0; i < words.size(); i++)
{
mubiao[words[i]]++;
}
vector<int>daan; //记录答案
//从不同的起点出发,获取所有的可能性
for (int i = 0; i < words[0].size(); i++)
{
int count = 0; //记录符合条件的单词数
unordered_map<string, int>chazhao;
//滑动窗口
for (int left = i, right = i; right + words[0].size() <= s.size(); right += words[0].size())
{
//进窗口
string in = s.substr(right, words[0].size());
chazhao[in]++;
//判断
//当该单词在目标字符串中存在,且符合目标单词出现次数区间,计数器加一
if (mubiao.count(in) && chazhao[in] <= mubiao[in])
{
count++;
}
//出窗口
//当字符串大小超过目标大小则出窗口
if (right - left + 1 > words[0].size() * words.size())
{
string out = s.substr(left, words[0].size());
//当该单词在目标字符串中存在,且符合目标单词出现次数区间,计数器减一
if (mubiao.count(out) && chazhao[out] <= mubiao[out])
{
count--;
}
chazhao[out]--;
left += words[0].size();
}
//更新答案
//若有效单词数等于目标单词数则更新答案
if (count == words.size())
{
daan.push_back(left);
}
}
}
return daan;
}
};
Java算法代码:
class Solution
{
public List<Integer> findSubstring(String s, String[] words)
{
List<Integer> ret = new ArrayList<Integer>();
// 保存字典中所有单词的频次
Map<String, Integer> hash1 = new HashMap<String, Integer>();
for (String str : words) hash1.put(str, hash1.getOrDefault(str, 0) + 1);
int len = words[0].length(), m = words.length;
for (int i = 0; i < len; i++) // 执⾏次数
{
// 保存窗⼝内所有单词的频次
Map<String, Integer> hash2 = new HashMap<String, Integer>();
for (int left = i, right = i, count = 0; right + len <= s.length();
right += len)
{
// 进窗⼝ + 维护 count
String in = s.substring(right, right + len);
hash2.put(in, hash2.getOrDefault(in, 0) + 1);
if (hash2.get(in) <= hash1.getOrDefault(in, 0)) count++;
// 判断
if (right - left + 1 > len * m)
{
// 出窗⼝ + 维护 count
String out = s.substring(left, left + len);
if (hash2.get(out) <= hash1.getOrDefault(out, 0)) count--;
hash2.put(out, hash2.get(out) - 1);
left += len;
}
// 更新结果
if (count == m) ret.add(left);
}
}
return ret;
}
}