给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。用c++写出代码,要求时间复杂度为O(n2),空间复杂度为O(n),并说出解题思路
时间: 2024-02-21 20:01:45 浏览: 49
C++找出字符串中出现最多的字符和次数,时间复杂度小于O(n^2)
5星 · 资源好评率100%
以下是符合要求的 C++ 代码实现,时间复杂度为O(n^2),空间复杂度为O(n)。
```c++
class Solution {
public:
string removeDuplicateLetters(string s) {
int n = s.length();
vector<int> cnt(26, 0); // 统计每个字符出现的次数
vector<bool> vis(26, false); // 标记每个字符是否在栈中
string res = ""; // 结果字符串
for (int i = 0; i < n; i++) {
cnt[s[i] - 'a']++; // 统计每个字符出现的次数
}
for (int i = 0; i < n; i++) {
if (vis[s[i] - 'a']) { // 如果该字符已经在栈中,跳过
cnt[s[i] - 'a']--; // 更新该字符出现次数
continue;
}
while (!res.empty() && res.back() > s[i] && cnt[res.back() - 'a'] > 0) { // 栈不空,栈顶元素比当前元素大,且栈顶元素仍有剩余
vis[res.back() - 'a'] = false; // 标记栈顶元素已经弹出
res.pop_back(); // 弹出栈顶元素
}
res += s[i]; // 将当前元素入栈
vis[s[i] - 'a'] = true; // 标记当前元素已经入栈
cnt[s[i] - 'a']--; // 更新当前元素出现次数
}
return res;
}
};
```
解题思路:
1. 统计字符串中每个字符出现的次数;
2. 遍历字符串中的每个字符,如果该字符已经在栈中,则跳过该字符,否则将该字符入栈;
3. 在每次将字符入栈之前,先判断栈顶元素是否比该字符大,如果是,且栈顶元素在后面的字符串中还有剩余,则弹出栈顶元素,直到栈顶元素比该字符小或者栈为空为止;
4. 如果当前字符入栈,标记该字符已经在栈中,并更新该字符出现的次数;
5. 最后返回栈中的字符即可。
该算法的时间复杂度为O(n^2),因为在每次入栈之前,需要遍历栈中的元素,直到找到比当前元素小的元素为止。具体来说,在最坏情况下,每个字符都需要遍历栈中所有的元素,因此总的时间复杂度为O(n^2)。该算法的空间复杂度为O(n),因为需要使用一个辅助栈和两个辅助数组,它们的长度都是字符串的长度n。
阅读全文