【c++&Leetcode】232. Implement Queue using Stacks

文章讨论了C++中使用迭代器实现队列的两种方法,比较了使用stack和vector的不同策略,并强调了迭代器在通用性、安全性、灵活性等方面的优势。作者还提及了迭代器与指针的区别以及其在数据结构中的重要性。
摘要由CSDN通过智能技术生成

问题入口

他人思路(时间复杂度更低)

  • 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. **功能性:** 迭代器可以提供特定于与之关联的容器的附加功能,例如双向或随机访问能力,这些功能可能在指针中不可用。

因此,虽然迭代器和指针在解引用以访问值的方式上有一些相似之处,但它们用途不同,提供不同级别的抽象和安全性。在与标准容器一起工作时,使用迭代器可以确保更安全和更容器无关的代码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!对于LeetCode上的问题994.腐烂的橘子,你可以使用Python来解决。下面是一个示例代码: ```python from collections import deque def orangesRotting(grid): # 记录网格的行数和列数 row, col = len(grid), len(grid[0]) # 定义四个方向:上、下、左、右 directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 使用队列来保存腐烂的橘子的位置 queue = deque() # 记录新鲜橘子的数量 fresh_count = 0 # 遍历整个网格,初始化队列和新鲜橘子的数量 for i in range(row): for j in range(col): if grid[i][j] == 2: # 腐烂的橘子 queue.append((i, j)) elif grid[i][j] == 1: # 新鲜橘子 fresh_count += 1 # 如果新鲜橘子的数量为0,直接返回0 if fresh_count == 0: return 0 # 初始化分钟数 minutes = 0 # 开始进行BFS,直到队列为空 while queue: # 记录当前分钟数下,队列中的元素数量 size = len(queue) # 遍历当前分钟数下的所有腐烂的橘子 for _ in range(size): x, y = queue.popleft() # 遍历四个方向 for dx, dy in directions: nx, ny = x + dx, y + dy # 判断新位置是否在网格内,并且是新鲜橘子 if 0 <= nx < row and 0 <= ny < col and grid[nx][ny] == 1: # 将新鲜橘子变为腐烂状态 grid[nx][ny] = 2 # 将新鲜橘子的位置加入队列 queue.append((nx, ny)) # 新鲜橘子的数量减1 fresh_count -= 1 # 如果当前分钟数下,没有新鲜橘子了,结束循环 if fresh_count == 0: break # 每遍历完一层,分钟数加1 minutes += 1 # 如果最后还有新鲜橘子,返回-1,否则返回分钟数 return -1 if fresh_count > 0 else minutes ``` 你可以将给定的网格作为参数传递给`orangesRotting`函数来测试它。请注意,该代码使用了BFS算法来遍历橘子,并计算腐烂的分钟数。希望能对你有所帮助!如果有任何疑问,请随时问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值