LeetCode队列算法题——题解与思路

一、队列结构

1.设计循环队列

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

你的实现应该支持如下操作:

  • MyCircularQueue(k): 构造器,设置队列长度为 k 。
  • Front: 从队首获取元素。如果队列为空,返回 -1 。
  • Rear: 获取队尾元素。如果队列为空,返回 -1 。
  • enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
  • deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
  • isEmpty(): 检查循环队列是否为空。
  • isFull(): 检查循环队列是否已满。

题解思路:

创建k长度数组作为队列存储结构,分别定义head、tail两个指针,当队列为空时默认head、tail为-1。

enqueue(value)元素入队:第一个元素入队时,head、tail分别向右移动,而后元素入列时只有tail向后移动一位并将元素添加到数组的对应位置。

dequeue()元素出队:按照队列FIFO(先进先出)原则,依次将head位置上的元素移除并将head向右移动一位。

front、rear:分别取出head、tail在数组中对应位置的元素。

isEmpty():队列是否为空的判断方式是,初始状态下head==tail==-1,而当队列中有元素调用dequeue将元素全部移出时,判断head是否和tail指针相遇,这时将head与tail都置为-1即可。

isFull():判断队列是否已满两种情况为,当head==0 tail ==size-1时,或tail+1 == head时,可简化为(tail+1)%size == head。

class MyCircularQueue {
private int[] queue;
    private int head = -1, tail = -1;
    private int size;

    /**
     * Initialize your data structure here. Set the size of the queue to be k.
     */
    public MyCircularQueue(int k) {
        queue = new int[k];
        this.size = k;
    }

    /**
     * Insert an element into the circular queue. Return true if the operation is successful.
     */
    public boolean enQueue(int value) {
        if (isFull())
            return false;
        if (isEmpty()) {
            head++;
        }
        // 队尾指针移动
        tail = (tail + 1) % size;
        queue[tail] = value;
        return true;
    }

    /**
     * Delete an element from the circular queue. Return true if the operation is successful.
     */
    public boolean deQueue() {
        if (isEmpty())
            return false;
        ;
        if (head == tail) // 队列中所有元素都完成出队
            head = tail = -1;
        else
            head = (head + 1)%size;
        return true;
    }

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

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

    /**
     * Checks whether the circular queue is empty or not.
     */
    public boolean isEmpty() {
        return head == -1 && tail == -1;
    }

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

注:此方式并非运行最优解,却是思路最好理解的。

二、队列和广度优先搜索(BFS)

1.岛屿计算

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

题解思路:

采用BFS思想,首先遍历每个点判断是否是'1',如为'1'陆地数量+1,并将该点坐标入列并继续遍历其上下左右的点是否为'1',同时并将此点置为'0'避免后续遍历重复计算。

public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0)
            return 0;
        int num = 0;
        int ySize = grid.length;
        int xSize = grid[0].length;
        for (int i = 0; i < ySize; i++) {
            for (int j = 0; j < xSize; j++) {
                char cur = grid[i][j];
                if (cur == '1') {
                    num++;
                    // num++后将该点置为'0'避免重复计算
                    grid[i][j] = '0';
                    Queue<Integer> queue = new LinkedList<>();
                    // 将元素为'1'点的坐标入列
                    queue.offer(i * xSize + j);
                    while (!queue.isEmpty()) {
                        int id = queue.remove();
                        int row = id / xSize;
                        int col = id % xSize;
                        if (row >= 1 && grid[row - 1][col] == '1') {
                            grid[row - 1][col] = '0';
                            queue.offer((row - 1) * xSize + col);
                        }
                        if (row < ySize - 1 && grid[row + 1][col] == '1') {
                            grid[row + 1][col] = '0';
                            queue.offer((row + 1) * xSize + col);
                        }
                        if (col >= 1 && grid[row][col - 1] == '1') {
                            grid[row][col - 1] = '0';
                            queue.offer(row * xSize + col - 1);
                        }
                        if (col < xSize - 1 && grid[row][col + 1] == '1') {
                            grid[row][col + 1] = '0';
                            queue.offer(row * xSize + col + 1);
                        }
                    }

                }
            }
        }
        return num;
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值