Priority queue

The underlying data structure that priority queues rely on is typically the heap.

Classification: heap and small heap

If the root is bigger than the left and right children, it’s called a heap. The root is smaller than the left and right children, so it’s called a small heap, and the root of a large heap is the maximum, and the root of a small heap is the minimum. Adjusting the heap time to O(LGN) every time there is an element push or pop is also very fast.

said

Most of the time, arrays are used to represent a heap, not binary trees. This is because:

  • The memory of the array is continuous and the access speed is faster.
  • The heap structure is a complete binary tree.

The rules of heap are as follows:

  • The parent of I is par = (i-1)/2
  • The left child of I is 2 times I plus 1
  • The right child of I is 2 times I plus 2

operation

sinking

    /** * sink O(lgN) */
    private void sink(int i) {
        int j = 0;
        int t = arr[i];
        while ((j = (i << 1) + 1) < n) {
            if (j < n - 1 && arr[j] < arr[j + 1]) {
                j++;
            }

            if (arr[j] > t) {
                arr[i] = arr[j];
                i = j;
            } else {
                break;
            }
        }
        arr[i] = t;
    }
Copy the code

floating

    /** * float up O(lgN) */
    private void swim(int i) {
        int j = 0;
        int t = arr[i];
        while (i > 0) {
            j = (i - 1) > >1;
            if (arr[j] < t) {
                arr[i] = arr[j];
                i = j;
            } else {
                break;
            }
        }
        arr[i] = t;
    }
Copy the code

POP

    /**
     * pop
     *
     * @return* /
    private int pop(a){
        int ret =arr[0];
        arr[0] = arr[--n];
        sink(0);
        return ret;
    }
Copy the code

push

    /** * push */
    private void push(int v){
        arr[n++] = v;
        swim(n-1);
    }
Copy the code

Queue size

 /**
   * 队列大小
   */
 private int size(a) {
     return n;
 }
Copy the code

The smallest number of K

Given an array a[], return the smallest K number in the array

Input: A=[3,2,1], k=2

Output: [2, 1]

    private int[] getLeastNumbers(int[] a, int k) {
        if (k < 0 || a == null || a.length == 0) {
            return new int[0];
        }

        arr = new int[a.length];
        n = 0;
        for (int x : a) {
            push(x);
            if(size() > k) { pop(); }}int[] resultArr = new int[k];
        int i = 0;
        while (size() > 0) {
            resultArr[i++] = pop();
        }
        return resultArr;
    }
Copy the code

jumping

Title: Suppose you are playing a jumping game. There are two ways to jump from a low place to a high place. Method 1: Stuff blocks, but there is a limit to how many blocks you can have. For simplicity, the height difference is the number of bricks you need. Method 2: Use ladders. Ladders can ignore the height difference (you can assume you can climb even higher), but there are a limited number of ladders (one can only be used once). The rest of the jump can be done flat, or from a high place to a low place, without any help. You are given an array of different heights. Suppose you always start at index = 0. So, what’s the furthest you can jump?

Enter: [3, 1, 6, 20, 10, 20], bricks = 5, landers = 1

Output: 4

private int furthestBuilding(int[] heights, int bricks, int ladders) {

        // Take care to handle illegal input
        if (heights == null || heights.length == 0) {
            return -1;
        }

        Queue<Integer> queue = new PriorityQueue<>((v1, v2) -> v2 - v1);
        int sum =0;
        int lastPos =0;
        int preHeight = heights[0];

        for (int i=1; i< heights.length; i++){
            final int curHeight = heights[i];
            if(preHeight >= curHeight){
                lastPos = i;
            } else {
                final int delta = curHeight - preHeight;
                queue.offer(delta);
                sum += delta;
                while(sum > bricks && ladders > 0){
                    sum -= queue.peek();
                    queue.poll();
                    ladders--;
                }
                if(sum <= bricks){
                    lastPos =i;
                }else {
                    break;
                }
            }
            preHeight = curHeight;
        }
        return lastPos;
    }
Copy the code

Number of refueling times

private int minRefuelStops(int target, int startFuel, int[][] stations) {
        int i = 0;
        int curPos = 0;
        int fuelLeft = startFuel;
        Queue<Integer> queue = new PriorityQueue<>((v1, v2) -> v2 - v1);
        int addFuelTimes = 0;
        while (curPos + fuelLeft < target) {
            int pos = target;
            int fuel =0;

            if(i< stations.length && stations[i][0] <= target){
                pos = stations[i][0];
                fuel = stations[i][1];
            }

            while(curPos +fuelLeft < pos){
                if(queue.isEmpty()){
                    return -1;
                }

                final int curMaxFuel = queue.peek();
                queue.poll();
                fuelLeft +=curMaxFuel;
                addFuelTimes ++;
            }

            final int fuelCost = pos - curPos;
            fuelLeft -= fuelCost;
            curPos = pos;

            if(fuel > 0){
                queue.offer(fuel);
            }
            i++;
        }
        return curPos + fuelLeft > target? addFuelTimes: -1;
    }
Copy the code