代码随想录 Day3 - 栈和队列 ② 4~5
Carl 语录
提醒
个人总结
一句话
- 访问容器中的元素前,必须判空。 对于任何容器类型,在访问其元素前,必须先检查容器是否为空,以避免出现未定义行为。
- 否则,若容器为空,访问其元素为非法行为,会引发 未定义行为。如在一个空的vector上使用front()或back()函数,就会引发未定义行为。
- for( auto 范围变量名:范围表达式) 进行遍历。
- ** for (auto iter = v.begin(); iter != v.end(); ++iter) {std::cout << *iter << ’ ';} ** 进行遍历。
20. 有效的括号
实现目标:
每一个出现的右括号(反括号)都与左括号匹配
思路:
- 使用 栈:每出现一个右括号,出栈一个左括号,判断是否匹配。
实现过程:
- 从头开始遍历,每发现一个左括号,压入栈中;
- 每发现一个右括号,栈顶元素出栈,判断是否匹配:若匹配则true
代码:
class Solution {
public:
bool isValid(string s) {
stack<char> c;
for(int i = 0; i < s.length(); i++){
//检测到左括号,则压入栈
if(s[i] == '(' || s[i] == '[' || s[i] == '{'){
c.push(s[i]);
}
//检测到右括号
else{
// 若栈为空(即右括号多余)
if(c.empty()) return false;
//或栈顶元素不匹配,即则返回false
if( (s[i] == ')' && c.top() != '(')
|| (s[i] == ']' && c.top() != '[')
|| (s[i] == '}' && c.top() != '{') ) return false;
//若栈不为空,且栈顶元素与其相匹配,则出栈栈顶元素
c.pop();
}
}
//此时已经遍历完成,若栈中仍有元素(即左括号多余,则返回false
if(!c.empty()) return false;
return true;
}
};
1047. 删除字符串中的所有相邻重复项
实现目标:
每次都删除当前相邻且重复的两个元素。删除所有重复组后按原来的顺序输出。
思路:
- 用队列,将元素放入队尾,用下一元素与队尾进行对比,若相同则删去两个元素。再次对比。
实现过程:
- 删除多余元素。 队尾元素与新元素对比。记得访问元素前要 对容器判空。
- deque类型转换为string。 用 空string(“”) 逐个添加队列中的字符。
代码:
- 时间复杂度: O(n)
- 空间复杂度: O(n)
class Solution {
public:
string removeDuplicates(string s) {
deque<char> queue;
//注意:front()和back()函数的前提条件是容器中必须至少存在一个元素。
//如果容器为空,则调用这两个函数会导致未定义行为。
//故要访问容器的首尾元素时,首先要进行判空,可用empty()或size()
//是的,对于任何容器类型,在访问其中的元素之前,都需要先检查容器是否为空,以避免出现未定义行为。
//这不仅适用于 deque(双端队列),也适用于其他序列容器,如 vector、list、forward_list、array 等。
//甚至对于关联容器,如 set、map、unordered_set、unordered_map 等,在访问其中的元素之前,也需要检查容器是否为空。
queue.push_back(s[0]);
for(int i = 1; i < s.length(); i++){
//如果队列不为空,且新元素与队尾元素相同,则删去队尾元素
if(!queue.empty() && queue.back() == s[i]) queue.pop_back();
//若队列为空,或二者不相同,则将新元素添加至队尾
else queue.push_back(s[i]);
}
//将队列中的元素按从前到后的顺序一个一个地添加到 空string 后
string result="";
while(!queue.empty()){
result += queue.front();
//front()只是访问元素,pop_front()才是删去队首元素
queue.pop_front();
}
return result;
}
};
Carl 的优解
当然可以拿字符串直接作为栈,这样省去了栈还要转为字符串的操作。
- 时间复杂度: O(n)
- 空间复杂度: O(1), 返回值不计空间复杂度
代码如下:
class Solution {
public:
string removeDuplicates(string S) {
string result;
for(char s : S) {
if(result.empty() || result.back() != s) {
result.push_back(s);
}
else {
result.pop_back();
}
}
return result;
}
};