数据结构-随看-队列

数据结构-随看-队列

  1. 队列

    • 可以使用动态数组和指向队列头部的索引:List data = new List<>();

    • 更有效的方法是使用循环队列。即使用固定大小的数组两个指针来指示起始位置和结束位置。

    • 循环队列-实现

    • class MyCircularQueue {
          
          private int[] data;
          private int head;
          private int tail;
          private int size;
      
          /** Initialize your data structure here. Set the size of the queue to be k. */
          public MyCircularQueue(int k) {
              data = new int[k];
              head = -1;
              tail = -1;
              size = k;
          }
          
          /** Insert an element into the circular queue. Return true if the operation is successful. */
          public boolean enQueue(int value) {
              if (isFull() == true) {
                  return false;
              }
              if (isEmpty() == true) {
                  head = 0;
              }
              tail = (tail + 1) % size;
              data[tail] = value;
              return true;
          }
          
          /** Delete an element from the circular queue. Return true if the operation is successful. */
          public boolean deQueue() {
              if (isEmpty() == true) {
                  return false;
              }
              if (head == tail) {
                  head = -1;
                  tail = -1;
                  return true;
              }
              head = (head + 1) % size;
              return true;
          }
          
          /** Get the front item from the queue. */
          public int Front() {
              if (isEmpty() == true) {
                  return -1;
              }
              return data[head];
          }
          
          /** Get the last item from the queue. */
          public int Rear() {
              if (isEmpty() == true) {
                  return -1;
              }
              return data[tail];
          }
          
          /** Checks whether the circular queue is empty or not. */
          public boolean isEmpty() {
              return head == -1;
          }
          
          /** Checks whether the circular queue is full or not. */
          public boolean isFull() {
              return ((tail + 1) % size) == head;
          }
      }
      
      /**
       * Your MyCircularQueue object will be instantiated and called as such:
       * MyCircularQueue obj = new MyCircularQueue(k);
       * boolean param_1 = obj.enQueue(value);
       * boolean param_2 = obj.deQueue();
       * int param_3 = obj.Front();
       * int param_4 = obj.Rear();
       * boolean param_5 = obj.isEmpty();
       * boolean param_6 = obj.isFull();
       */
      
    • java调用队列

    • Queue<Integer> q = new LinkedList();
      q.offer();
      q.poll();
      q.peek()//get the first element,but don't remove it.
      
  2. 队列和BFS(Broad First Search),找出从根节点到目标节点的最短路径

    • 和树的层次遍历类似:越是接近根节点的节点月早地遍历

    • 思路:我们先将根节点排入队列,然后再每一轮中,我们逐个处理已经在队列中的节点,并将所有邻居添加到队列中。

    • 节点的处理顺序和添加到队列的顺序时完全相同的顺序,所有在BFS中使用队列的原因。

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

    • 模板1

      • int BFS(Node root, Node target){
            Queue<Node> queue;
            int step = 0;
            add root to queue;
            //BFS
            while(queue is not empty){
                step = step + 1;
                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;
        }
        
      • 模板二:确保不会访问一个结点两次 添加一个哈希集

      • int BFS(Node root, Node target){
            Queue<Node> queue;
            Set<Node> used;
            int step = 0;
            add root to queue;
            add root to used;
            //BFS
            while(queue is not empty){
                step = step + 1;
                int size = queue.size();
                for(int i=0;i<size;++i){
                    Node cur = the first node in queue;
                    return step is 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;
        }
        
      • 岛屿数量:给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

        示例 1:

      • 输入:
        11110
        11010
        11000
        00000
        
        输出: 1
        预览
        

        示例 2:

        输入:
        11000
        11000
        00100
        00011
        
        输出: 3
        
      • 思路 首先明白岛屿的定义:一 1 周围全是 0,即为一个岛屿。(注意:grid 数组内的 1、0 均为char型字符,非整型)

        示例1 中所有 1 都可以连接到一起,即所有 1 组成一个岛屿。示例2 中的三个岛屿:左上角四个1、中间一个1、右下角一个一,分别组成三个岛屿。

      • BFS:从一个为1的根节点开始访问,每次向下访问一个结点,知道访问到最后一个顶点。

      • class Solution{
            public int numIslands(char[][] grid){
                if(grid == null || grid.length == 0) return 0;
                int row = grid.length, column = grid[0].length, count=0;
                for(int i=0;i<row;i++){
                    for(int j =0;j<column;j++){
                        if(grid[i][j] == '1'){
                            bfs(grid,i,j,row,column);
                            count++;
                        }
                    }
                }
                return count;
            }
            
            private void bfs(char[][] grid, int i,int j, int row, int column){
                Queue<Integer> loc = new LinkedList<>();
                loc.add(i*column+j);
                while(!loc.isEmpty()){
                    int id = loc.remove();
                    int r = id / column, c = id % column;
                    if(r - 1 >= 0 && grid[r-1][c] == '1'){
                        loc.add((r-1)*column + c);
                        grid[r-1][c]= '0';
                    }
                    if(r + 1 < row && grid[r+1][c] == '1'){
                        loc.add((r+1)*column + c);
                        grid[r+1][c] = '0';
                    }
                    if(c - 1 >=0 && grid[r][c-1] == '1'){
                        loc.add(r*column +c-1);
                        grid[r][c-1] = '0';
                    }
                    if(c + 1 >= 0 && grid[r][c+1] == '1'){
                        loc.add(r*column + c+ 1);
                        grid[r][c+1]='0';
                    }            
                }
            }
        }
        
发布了94 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_31900497/article/details/104276280