heapify

// Version Linpz
public class Solution {
    /**
     * @param A: Given an integer array
     * @return: void
     */
    private void siftdown(int[] A, int k) {
        while (k * 2 + 1 < A.length) {
            int son = k * 2 + 1;
            if (k * 2 + 2 < A.length && A[son] > A[k * 2 + 2])
                son = k * 2 + 2;
            if (A[son] >= A[k])
                break;

            int temp = A[son];
            A[son] = A[k];
            A[k] = temp;
            k = son;
        }
    }

    public void heapify(int[] A) {
        for (int i = (A.length - 1) / 2; i >= 0; i--) {
            siftdown(A, i);
        }
    }
}

// Version 1: this cost O(n)
public class Solution {
    /**
     * @param A: Given an integer array
     * @return: void
     */
    private void siftdown(int[] A, int k) {
        while (k < A.length) {
            int smallest = k;
            if (k * 2 + 1 < A.length && A[k * 2 + 1] < A[smallest]) {
                smallest = k * 2 + 1;
            }
            if (k * 2 + 2 < A.length && A[k * 2 + 2] < A[smallest]) {
                smallest = k * 2 + 2;
            }
            if (smallest == k) {
                break;
            }
            int temp = A[smallest];
            A[smallest] = A[k];
            A[k] = temp;

            k = smallest;
        }
    }

    public void heapify(int[] A) {
        for (int i = A.length / 2; i >= 0; i--) {
            siftdown(A, i);
        } // for
    }
}


// Version 2: This cost O(nlogn)
public class Solution {
    /**
     * @param A: Given an integer array
     * @return: void
     */
    private void siftup(int[] A, int k) {
        while (k != 0) {
            int father = (k - 1) / 2;
            if (A[k] > A[father]) {
                break;
            }
            int temp = A[k];
            A[k] = A[father];
            A[father] = temp;

            k = father;
        }
    }

    public void heapify(int[] A) {
        for (int i = 0; i < A.length; i++) {
            siftup(A, i);
        }
    }
}

ugly number ii

     public int nthUglyNumber(int n) {

         PriorityQueue<Integer> pq = new PriorityQueue<>();
         Set<Integer> set = new HashSet<>();
         int[] prime = new int[] {2,3,5};
         pq.add(1);
         for (int i = 0; i < 3; i++) {
             pq.add(prime[i]);
             set.add(prime[i]);
         }

         int rst = 0;
         for (int i = 0; i < n - 1; i++) {
             rst = pq.poll();
             for (int j = 0; j < 3; j++) {
                if (set.contains(rst * prime[j]) 
                    || rst > Integer.MAX_VALUE / prime[j]) continue;
                pq.add(rst * prime[j]);
                set.add(rst*prime[j]);
             }
         }

         return pq.peek();
     }

top k largest number ii

public class Solution {
    private int maxSize;
    private Queue<Integer> minheap;
    public Solution(int k) {
        minheap = new PriorityQueue<>();
        maxSize = k;
    }

    public void add(int num) {
        if (minheap.size() < maxSize) {
            minheap.offer(num);
            return;
        }

        if (num > minheap.peek()) {
            minheap.poll();
            minheap.offer(num);
        }
    }

    public List<Integer> topk() {
        Iterator it = minheap.iterator();
        List<Integer> result = new ArrayList<Integer>();
        while (it.hasNext()) {
            result.add((Integer) it.next());
        }
        Collections.sort(result, Collections.reverseOrder());
        return result;
    }
};

data stream median

    public int[] medianII(int[] nums) {  
        // write your code here  
        if(nums==null) return null;  
        int[] res = new int[nums.length];  

        PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();  
        PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(11, new Comparator<Integer>() {  
            @Override  
            public int compare(Integer x, Integer y) {  
                return y-x;  
            }  
        });  
        res[0] = nums[0];  
        maxHeap.add(nums[0]);  

        for(int i=1; i<nums.length; i++) {  
            int x = maxHeap.peek();  
            if(nums[i] <= x) {  
                maxHeap.add(nums[i]);  
            } else {  
                minHeap.add(nums[i]);  
            }  

              while (minHeap.size() >= maxHeap.size() + 1) {  
                maxHeap.offer(minHeap.poll());
              }
              while (maxHeap.size() > minHeap.size() + 1) {
                minHeap.offer(maxHeap.poll());
              }
              res[i] = maxHeap.peek();  
        }  
        return res;  
    }

kth smallest numbers in matrix

  • min heap
  • pop() * k
public class Solution {
    /**
     * @param matrix: a matrix of integers
     * @param k: an integer
     * @return: the kth smallest number in the matrix
     */
    public int kthSmallest(int[][] matrix, int k) {
        // write your code here

        int rows = matrix.length;
        int cols = matrix[0].length;

        PriorityQueue<Point> pq = new PriorityQueue<Point>(k, new PointComparator());
        for (int i = 0; i < rows; i++) {
            pq.offer(new Point(i, 0, matrix[i][0]));
        }

        for (int i = 0; i < k - 1; i++) {
            Point p = pq.poll();
            if (p.col == cols - 1) {
                continue;
            }
            pq.offer(new Point(p.row, p.col+1, matrix[p.row][p.col+1]));
        }

        return pq.poll().val;
    }
}

class Point {
    int row, col, val;

    public Point(int row, int col, int val) {
        this.row = row;
        this.col = col;
        this.val = val;
    }
}

class PointComparator implements Comparator<Point> {
    public int compare(Point A, Point B) {
        return A.val - B.val;
    }
}

data stream median

  • maxHeap - normal class, hold small part numbers. always have equal or one more element. when odd, maxHeap.peek()
  • minHeap - top class, hold larger part numbers. when even, (minHeap.peek() + maxHeap.peek()) / 2
  • adjust minHeap and maxHeap
    • when size are different -> move to minHeap
    • when coming largest in maxHeap is larger than smallest in minHeap && minHeap is not null -> swap
class MedianFinder {

    /** initialize your data structure here. */
    PriorityQueue<Integer> maxHeap;
    PriorityQueue<Integer> minHeap;
    int count;

    public MedianFinder() {
        minHeap = new PriorityQueue<>();
        maxHeap = new PriorityQueue<>((v1, v2) -> v2 - v1);
        count = 0;
    }

    public void addNum(int num) {
        count = (count + 1) % 2;
        maxHeap.offer(num);

        if (minHeap.size() > 0) {
            if (minHeap.peek() < maxHeap.peek()) {
                minHeap.offer(maxHeap.poll());
                maxHeap.offer(minHeap.poll());
            }
        }

        if (maxHeap.size() - minHeap.size() > 1) {
            minHeap.offer(maxHeap.poll());
        }        
    }

    public double findMedian() {
        if (count == 1) 
            return maxHeap.peek();
        else 
            return (maxHeap.peek() + minHeap.peek()) / 2.0;        
    }
}
    PriorityQueue<Integer> minHeap = new PriorityQueue<>();//heap is a minimal heap by default
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());//change to a maximum heap

// Adds a number into the data structure.
public void addNum(int num) {
    maxHeap.offer(num);
    minHeap.offer(maxHeap.poll());
    if (maxHeap.size() < minHeap.size())
        maxHeap.offer(minHeap.poll());
}

// Returns the median of current data stream
public double findMedian() {
    if (maxHeap.size() == minHeap.size())
        return (maxHeap.peek() + minHeap.peek()) / 2.0;
    else
        return maxHeap.peek();
}

sliding window median

approach i: minHeap and maxHeap

    • notice: remove element
    • O(nk), remove(num) is O(k)
  • approach ii: treeSet
    • O(nlogk)
    • use treeSet instead of PriorityQueue, notice to dedup, use Node(index, num[index])
  • TreeSet vs Heap
    • TreeSet remove is O(logn), Heap is O(n)
    • Add, both are O(logn)
    • TreeSet does not allow duplicate
public class Solution {
    PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
    PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>((v1,v2) -> v2.compareTo(v1)); // v2-v1 will exceed limit

    public double[] medianSlidingWindow(int[] nums, int k) {
        int n = nums.length - k + 1;
        if (n <= 0) return new double[0];
        double[] result = new double[n];

        for (int i = 0; i < nums.length; i++) {
            add(nums[i]);
            if (i >= k) remove(nums[i-k]);
            if (i + 1 >= k) result[i+1-k] = getMedian();            
        }

        return result;
    }

    private void add(int num) {
        maxHeap.offer(num);
        minHeap.offer(maxHeap.poll());

        if (minHeap.size() > maxHeap.size()) {
            maxHeap.offer(minHeap.poll());
        }
    }

    private void remove(int num) {
        if (maxHeap.contains(num)) {
            maxHeap.remove(num);
        }
        else {
            minHeap.remove(num);        
        }

        if (minHeap.size() > maxHeap.size()) {  // when remove from maxHeap, maxHeap may have one less elements
            maxHeap.offer(minHeap.poll());
        }

        if (maxHeap.size() - minHeap.size() > 1) {  // when remove from minHeap, maxHeap may have two more elements
            minHeap.offer(maxHeap.poll());
        }
    }

    private double getMedian() {
        if (maxHeap.isEmpty() && minHeap.isEmpty()) return 0;

        if (maxHeap.size() == minHeap.size()) {
            return ((double)maxHeap.peek() + (double)minHeap.peek()) / 2.0;
        }
        else {
            return (double)maxHeap.peek();
        }
    }
}

sliding window maximum:

  • deque

sliding window template

Maximum Average Subarray I

class Solution {
    public double findMaxAverage(int[] nums, int k) {
        int sum = 0;
        int max = Integer.MIN_VALUE;

        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            if (i - k >= 0) sum -= nums[i-k];
            if (i - k + 1 >= 0) max = Math.max(max, sum);
        }

        return (double) max/k;        
    }
}

Maximum Average Subarray ii

  • ??

results matching ""

    No results matching ""