他人思路(时间复杂度更低)
- Time complexity:
- push : O(n);
- peek : O(1);
- pop : O(1);
- empty: O(1);
依照这位大佬的思路写下的代码:
class MyQueue2 {
public:
stack<int> s1;
stack<int> s2;
MyQueue() {
}
void push(int x) {
while (!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
s1.push(x);
while (!s2.empty())
{
s1.push(s2.top());
s2.pop();
}
}
int pop() {
int ret = s1.top();
s1.pop();
return ret;
}
int peek() {
return s1.top();
}
bool empty() {
return s1.empty();
}
};
My way
我不知道为什么死活要用vector,如果我知道c++有stack库我铁定不用vector。
不过熟悉了一些vector基本操作还不错。请欣赏并不优美的代码:
class MyQueue {
public:
vector<int> stack1;
vector<int> stack2;
int size;
MyQueue() {
size = 0;
}
void push(int x) {
stack1.push_back(x);
size++;
stack2.assign(stack1.rbegin(), stack1.rend());
}
int pop() {
int ret = *(stack2.end()-1);
stack2.pop_back();
size--;
stack1.assign(stack2.rbegin(), stack2.rend());
return ret;
}
int peek() {
return *(stack1.begin());
}
bool empty() {
return size == 0? true:false;
}
};
扩展
另外我对迭代器有一些好奇,以下是咨询chatgpt相关问题得到的回答。
使用迭代器与直接索引访问容器相比,具有一些不同的特点和优势:
1. **通用性:** 迭代器是一种通用的访问容器元素的方式,适用于各种不同类型的容器(例如,向量、列表、集合、映射等)。这使得您的代码更加通用,能够适用于不同的数据结构,而不需要修改大部分代码。
2. **安全性:** 使用迭代器可以提高代码的安全性。索引访问容器时,如果索引越界,将导致未定义行为或程序崩溃。而使用迭代器可以更容易地避免这种问题,因为迭代器通常会在容器的开头和结尾进行有效性检查。
3. **灵活性:** 迭代器可以支持正向和反向迭代,因此可以轻松实现从前向后和从后向前的遍历。这在某些情况下非常有用,例如需要逆序访问容器的情况。
4. **容器修改:** 迭代器允许在遍历容器时修改容器中的元素。这对于在遍历过程中执行插入、删除或修改操作非常有用。在索引访问中,这样的操作可能导致迭代过程中的错误。
5. **范围定义:** 迭代器可以用来定义特定范围的元素。通过指定范围的开始和结束迭代器,您可以轻松地操作这个范围内的元素,而无需考虑容器的大小。
6. **适应性:** 一些容器不支持索引访问,例如 `std::list` 和 `std::set`,但它们仍然支持迭代器,因此迭代器是访问这些容器的唯一方法。
综上所述,使用迭代器通常是更灵活、更安全、更通用的方法,特别是当涉及不同类型的容器和复杂的操作时。但对于某些简单的情况,直接索引访问也可能更加方便。选择使用哪种方法取决于您的需求和代码的复杂性。
我可以说迭代器类似于指针吗?因为它们都需要使用 * 运算符来访问值。
是的,你可以将C++中的迭代器视为某种程度上类似于指针。它们都提供了一种访问元素值的方法,你可以使用`*`运算符对它们进行解引用并访问它们指向的值。但是,迭代器和指针之间存在一些重要的区别:
1. **抽象层次:** 迭代器提供了比指针更高级的抽象。虽然指针可以用于低级别的数组和内存导航,但迭代器专门设计用于以更安全和更抽象的方式导航数据结构,如容器(例如向量、列表、映射)。
2. **容器独立性:** 迭代器不仅限于数组或连续的内存块。它们可以与不同类型的容器一起使用,并可以适应不同的容器实现。指针通常用于低级内存操作,不具备容器无关性。
3. **安全性:** 迭代器通常比指针更安全,因为它们可以包括边界检查,确保不会访问容器的有效范围之外的元素。指针没有内置的这种安全功能。
4. **复杂性:** 与指针相比,某些迭代器可能更复杂,特别是处理诸如`std::map`或`std::list`等容器时。迭代器可能需要处理非连续内存位置的遍历。
5. **功能性:** 迭代器可以提供特定于与之关联的容器的附加功能,例如双向或随机访问能力,这些功能可能在指针中不可用。
因此,虽然迭代器和指针在解引用以访问值的方式上有一些相似之处,但它们用途不同,提供不同级别的抽象和安全性。在与标准容器一起工作时,使用迭代器可以确保更安全和更容器无关的代码。