Every day a Leetcode
题目来源:2696. 删除子串后的字符串最小长度
解法1:暴力
暴力做法是不断把 AB 和 CD 去掉,直到 s 中没有 AB 和 CD 为止。
代码:
/*
* @lc app=leetcode.cn id=2696 lang=cpp
*
* [2696] 删除子串后的字符串最小长度
*/
// @lc code=start
class Solution
{
public:
int minLength(string s)
{
// 特判
if (s.empty())
return 0;
int indexOfAB = s.find("AB"), indexOfCD = s.find("CD");
while (indexOfAB != string::npos || indexOfCD != string::npos)
{
if (indexOfAB != string::npos)
s = s.substr(0, indexOfAB) + s.substr(indexOfAB + 2);
indexOfCD = s.find("CD");
if (indexOfCD != string::npos)
s = s.substr(0, indexOfCD) + s.substr(indexOfCD + 2);
indexOfAB = s.find("AB"), indexOfCD = s.find("CD");
}
return s.length();
}
};
// @lc code=end
结果:
复杂度分析:
时间复杂度:O(n2),其中 n 是字符串 s 的长度。
空间复杂度:O(n),其中 n 是字符串 s 的长度。替换过程中生成的字符串需要 O(n) 的空间。
解法2:栈
用栈记录遍历过的,没有删除的字母。
如果当前字母是 B,且栈顶为 A,那么这两个字母都可以删除。同理,如果当前字母是 D,且栈顶为 C,那么这两个字母都可以删除。
否则,把当前字母入栈。
代码:
// 栈
class Solution
{
public:
int minLength(string s)
{
// 特判
if (s.empty())
return 0;
stack<char> stk;
for (char &c : s)
{
if (!stk.empty() && ((c == 'B' && stk.top() == 'A') || (c == 'D' && stk.top() == 'C')))
stk.pop();
else
stk.push(c);
}
return stk.size();
}
};
结果:
复杂度分析:
时间复杂度:O(n),其中 n 是字符串 s 的长度。
空间复杂度:O(n),其中 n 是字符串 s 的长度。