给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。
刚看到这题第一反应是使用滑动窗口+hashmap内部判断滑动窗口是否满足条件。于是码完代码测试后提交,发现超时。代码如下:
class Solution {
public:
bool check(unordered_map<char, int> org, unordered_map<char, int> cnt)
{
for (auto it : org) {
if (it.second > cnt[it.first]) return false;
}
return true;
}
string minWindow(string s, string t) {
int len1 = t.size();
int len2 = s.size();
int left = 0, right = 0;
int retLeft = 0, retRight = 0;
string ret;
unordered_map<char, int> org, cnt;
while (right < len1) ++org[t[right++]];
right = 0;
while (right < len2) {
++cnt[s[right++]];
bool checked = false;
while (check(org, cnt)) {
checked = true;
--cnt[s[left++]];
}
if (checked && (ret.size() == 0 || right - left + 1 < ret.size())) ret = s.substr(left - 1, right - left + 1);
if (ret.size() == len1) return ret;
}
return ret;
}
};
后翻越官方题解,发现和我的差不多,不过官方题解的 map 是放在全局变量的,没有跟随函数入参。试了一下将我代码中的map声明为全局变量,果然能通过了。代码如下:
class Solution {
public:
unordered_map<char, int> org, cnt;
bool check()
{
for (auto it : org) {
if (it.second > cnt[it.first]) return false;
}
return true;
}
string minWindow(string s, string t) {
int len1 = t.size();
int len2 = s.size();
int left = 0, right = 0;
int retLeft = 0, retRight = 0;
string ret;
while (right < len1) ++org[t[right++]];
right = 0;
while (right < len2) {
++cnt[s[right++]];
bool checked = false;
while (check()) {
checked = true;
--cnt[s[left++]];
}
if (checked && (ret.size() == 0 || right - left + 1 < ret.size())) ret = s.substr(left - 1, right - left + 1);
if (ret.size() == len1) return ret;
}
return ret;
}
};
于是又试了一下函数传参时使用引用传递,也能通过,代码如下:
class Solution {
public:
bool check(unordered_map<char, int> &org, unordered_map<char, int> &cnt)
{
for (auto it : org) {
if (it.second > cnt[it.first]) return false;
}
return true;
}
string minWindow(string s, string t) {
int len1 = t.size();
int len2 = s.size();
int left = 0, right = 0;
int retLeft = 0, retRight = 0;
string ret;
unordered_map<char, int> org, cnt;
while (right < len1) ++org[t[right++]];
right = 0;
while (right < len2) {
++cnt[s[right++]];
bool checked = false;
while (check(org, cnt)) {
checked = true;
--cnt[s[left++]];
}
if (checked && (ret.size() == 0 || right - left + 1 < ret.size())) ret = s.substr(left - 1, right - left + 1);
if (ret.size() == len1) return ret;
}
return ret;
}
};
总结:
函数传参时尽量不要使用占用较大内存的参数,参数占用栈内存过大,不仅出栈入栈时性能消耗较多,而且还有可能造成栈溢出,应尽量使用引用或指针。
这都是我司编码规范的要求,还是要熟记并且运用起来啊!