队列和栈

1.队列的实现

#include<iostream>
#include<vector>

using namespace std;

class MyQueue {
    private:
        // store elements
        vector<int> data;
        // a pointer to indicate the start position
        int p_start;
    public:
        MyQueue() {p_start = 0;}
        /** Insert an element into the queue. Return true if the operation is successful. */
        bool enQueue(int x) {
            data.push_back(x);
            return true;
        }
        /** Delete an element from the queue. Return true if the operation is successful. */
        bool deQueue() {
            if (isEmpty()) {
                return false;
            }
            p_start++;
            return true;
        };
        /** Get the front item from the queue. */
        int Front() {
            return data[p_start];
        };
        /** Checks whether the queue is empty or not. */
        bool isEmpty()  {
            return p_start >= data.size();
        }
};

int main() {
    MyQueue q;
    q.enQueue(5);
    q.enQueue(3);
    if (!q.isEmpty()) {
        cout << q.Front() << endl;
    }
    q.deQueue();
    if (!q.isEmpty()) {
        cout << q.Front() << endl;
    }
    q.deQueue();
    if (!q.isEmpty()) {
        cout << q.Front() << endl;
    }
}

在这种情况下很容易造成内存空间的浪费。

2.循环队列

注意这里内存大小k+1

#include<iostream>
using namespace std;

class MyCircularQueue {

private:
    int* data;
    int size;
    int head;
    int tail;
public:
    /** Initialize your data structure here. Set the size of the queue to be k. */
    MyCircularQueue(int k) {
        data = new int[k+1];
        size = k+1;
        head = 0;
        tail = 0;
    }

    /** Insert an element into the circular queue. Return true if the operation is successful. */
    bool enQueue(int value) {
        if(!isFull())
        {
            tail = (tail + 1)%size;
            data[tail] = value;
            return true;
        }
        return false;
    }

    /** Delete an element from the circular queue. Return true if the operation is successful. */
    bool deQueue() {
        if(isEmpty())
            return false;
        head = (head + 1) %size;
        return true;
    }

    /** Get the front item from the queue. */
    int Front() {
        if(isEmpty())
            return -1;
        return data[(head+1)%size];
    }

    /** Get the last item from the queue. */
    int Rear() {
        if(isEmpty())
            return -1;
        return data[tail];
    }

    /** Checks whether the circular queue is empty or not. */
    bool isEmpty() {
        if(head == tail)
            return true;
        return false;
    }

    /** Checks whether the circular queue is full or not. */
    bool isFull() {
        if((tail + 1) %size == head)
            return true;
        return false;
     }
};

int main() {
    MyCircularQueue q(3);
    cout<<q.enQueue(1)<<endl;
    cout<<q.enQueue(2)<<endl;
    cout<<q.enQueue(3)<<endl;
    cout<<q.enQueue(4)<<endl;

    cout<<q.Rear()<<endl;
    cout<<q.isFull()<<endl;
    cout<<q.deQueue()<<endl;
    cout<<q.enQueue(4)<<endl;
    cout<<q.Rear()<<endl;
}

3.队列和 BFS

BFS 的两个主要方案:遍历找出最短路径

(1)BFS模板1

/**
 * Return the length of the shortest path between root and target node.
 */
int BFS(Node root, Node target) {
    Queue<Node> queue;  // store all nodes which are waiting to be processed
    int step = 0;       // number of steps neeeded from root to current node
    // initialize
    add root to queue;
    // BFS
    while (queue is not empty) {
        step = step + 1;
        // iterate the nodes which are already in the queue
        int size = queue.size();
        for (int i = 0; i < size; ++i) {
            Node cur = the first node in queue;
            return step if cur is target;
            for (Node next : the neighbors of cur) {
                add next to queue;
            }
            remove the first node from queue;
        }
    }
    return -1;          // there is no path from root to target
}
  1. 如代码所示,在每一轮中,队列中的结点是等待处理的结点
  2. 在每个更外一层的 while 循环之后,我们距离根结点更远一步。变量 step 指示从根结点到我们正在访问的当前结点的距离。

(2)BFS模板2

有时,确保我们永远不会访问一个结点两次很重要。否则,我们可能陷入无限循环。如果是这样,我们可以在上面的代码中添加一个哈希集来解决这个问题。这是修改后的伪代码:

/**
 * Return the length of the shortest path between root and target node.
 */
int BFS(Node root, Node target) {
    Queue<Node> queue;  // store all nodes which are waiting to be processed
    Set<Node> used;     // store all the used nodes
    int step = 0;       // number of steps neeeded from root to current node
    // initialize
    add root to queue;
    add root to used;
    // BFS
    while (queue is not empty) {
        step = step + 1;
        // iterate the nodes which are already in the queue
        int size = queue.size();
        for (int i = 0; i < size; ++i) {
            Node cur = the first node in queue;
            return step if cur is target;
            for (Node next : the neighbors of cur) {
                if (next is not in used) {
                    add next to queue;
                    add next to used;
                }
            }
            remove the first node from queue;
        }
    }
    return -1;          // there is no path from root to target
}

200.岛屿的个数

给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

示例 1:

输入:
11110
11010
11000
00000

输出: 1

示例 2:

输入:
11000
11000
00100
00011

输出: 3

思路:循环遍历每个点,如果该点是0,则跳过;如果是1,加入队列并将该点改为0,避免重复访问。然后进行广搜,取出队首元素,搜索该点周围四个点,如果有1就加入队列,并将1改为0,否则就跳过,当队列空时,一块岛屿搜索完毕,岛屿数目加1。进入下一块搜索,如此下去。。。
搜索时注意数组是否越界

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        if(grid.empty() || grid[0].empty())
            return 0;
        int m = grid.size(), n = grid[0].size();
        int res = 0;
        queue<pair<int,int>> island;
        pair<int, int> pos;
      
        for(int i = 0; i < m;i++)
            for(int j = 0; j < n; j++)
            {
                if(grid[i][j] == '0')
                    continue;
                else
                {
                    pos.first = i;
                    pos.second = j;
                    island.push(pos);
                    grid[i][j] = '0';
                    while(!island.empty())
                    {
                        pos = island.front();
                        island.pop();
                        int x = pos.first;
                        int y = pos.second;
                        if(x-1 >= 0 && grid[x-1][y] == '1')
                        {
                            pos.first = x-1;
                            pos.second = y;
                            island.push(pos);
                            grid[x-1][y] = '0';
                        }
                        if(x+1 < m && grid[x+1][y] == '1')
                        {
                            pos.first = x+1;
                            pos.second = y;
                            island.push(pos);
                            grid[x+1][y] = '0';
                        }
                        if(y-1 >= 0 && grid[x][y-1] == '1')
                        {
                            pos.first = x;
                            pos.second = y-1;
                            island.push(pos);
                            grid[x][y-1] = '0';
                        }
                        if(y+1 < n && grid[x][y+1] == '1')
                        {
                            pos.first = x;
                            pos.second = y+1;
                            island.push(pos);
                            grid[x][y+1] = '0';
                        }
                    }
                    res++;
                }
                
            }
        return res;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值