美文网首页
堆, 堆树(最小堆/最大堆) - heap, treap

堆, 堆树(最小堆/最大堆) - heap, treap

作者: lc_fan | 来源:发表于2019-06-08 18:38 被阅读0次

概念

  1. 堆是一种逻辑结构,树是一种存储结构,两者是不同层面的东西,就像“中国人"和“成年人”一样不矛盾。

heap和tree结合,得了treap堆树。

  1. 堆树和二叉排序树
    以小根堆为例,堆的特点是双亲结点的关键字必然小于等于孩子结点的关键字,而两个孩子结点的关键字没有次序规定
    而二叉排序树中,每个双亲结点的关键字均大于左子树结点的关键字,均小于右子树j结点的关键字,也就是说,每个双亲结点的左右孩子的关键字有次序关系
    这样,当对两种树执行中序遍历后,二叉排序树会得到一个有序的序列,而堆不一定。

堆树的构造

堆其实是一个完全二叉树,可以用数组来表示。

  • 根节点下标为1, 0为temp空间
  • 若某个节点的下标为 i,则:
    • 左孩子的下标为 2 * i
    • 右孩子的下标为 2 * i + 1
    • 父节点的下标为 i/2

如何保持最小堆性质:往下调整 shiftDown,将较大的数往下移动,示例如下:
如何保持最大堆性质:往下调整 shiftUp,将较大的数往上移动

// 将 start 号节点向下调整直到 end
void ShiftDown(int start, int end) {
  heap[0] = heap[start];
  
  int i = start;
  int j = 2 * start; // 左孩子

  while(j <= end) {
    // 如果有右孩子且右孩子比左孩子小,将 j 保存至右孩子
    if(j < end && heap[j] > heap[j + 1]) {
      j++;
    }
    
    // 如果 start 号节点比孩子小,则无需调整
    if(heap[0] <= heap[j]) {
      break;
    }
    // 往下调整,将较大的数往下移动
    else {
      heap[i] = heap[j];
      i = j;
      j = 2 * j;
    }
  }
  
  heap[i] = heap[0]
}

// n / 2 为开始调整的位置,即最后一个双亲节点的位置
for(int i = n / 2; i > 0; i--) {
  shiftDown(i, n);
}

实践应用

347. Top K Frequent Elements Medium
Given a non-empty array of integers, return the k most frequent elements.

Example 1:
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]

Example 2:
Input: nums = [1], k = 1
Output: [1]
Note:

You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
Your algorithm's time complexity must be better than O(n log n), where n is the array's size.

class Solution {
  public List<Integer> topKFrequent(int[] nums, int k) {
    // build hash map : character and how often it appears
    HashMap<Integer, Integer> count = new HashMap();
    for (int n: nums) {
      count.put(n, count.getOrDefault(n, 0) + 1);
    }

    // init heap 'the less frequent element first'
    PriorityQueue<Integer> heap =
            new PriorityQueue<Integer>((n1, n2) -> count.get(n1) - count.get(n2));

    // keep k top frequent elements in the heap
    for (int n: count.keySet()) {
      heap.add(n);
      if (heap.size() > k)
        heap.poll();
    }

    // build output list
    List<Integer> top_k = new LinkedList();
    while (!heap.isEmpty())
      top_k.add(heap.poll());
    Collections.reverse(top_k);
    return top_k;
  }
}
  1. 692. Top K Frequent Words Medium
    Given a non-empty list of words, return the k most frequent elements.

Your answer should be sorted by frequency from highest to lowest. If two words have the same frequency, then the word with the lower alphabetical order comes first.

Example 1.

Input: ["i", "love", "leetcode", "i", "love", "coding"], k = 2
Output: ["i", "love"]
Explanation: "i" and "love" are the two most frequent words.
    Note that "i" comes before "love" due to a lower alphabetical order.
class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        Map<String, Integer> count = new HashMap();
        for (String word: words) {
            count.put(word, count.getOrDefault(word, 0) + 1);
        }
        List<String> candidates = new ArrayList(count.keySet());
        Collections.sort(candidates, (w1, w2) -> count.get(w1).equals(count.get(w2)) ?
                w1.compareTo(w2) : count.get(w2) - count.get(w1));

        return candidates.subList(0, k);

Ref:

  1. 数学lover知乎回答
  2. 专职跑龙套简书
  3. leetcode原题

相关文章

  • 堆, 堆树(最小堆/最大堆) - heap, treap

    概念 堆是一种逻辑结构,树是一种存储结构,两者是不同层面的东西,就像“中国人"和“成年人”一样不矛盾。 heap和...

  • 算法笔记之堆求取前N个元素

    堆(heap)是一种特殊的数据结构,它通常被看作是一棵树的数组对象,堆总是一颗完全二叉树。 堆分为最大堆和最小堆,...

  • 数据结构之「堆」

    堆 堆 是一种特殊的完全二叉树结构,通常,它有两种类型:最小堆 和 最大堆。 最小堆(min heap)是父节点的...

  • Treap(数堆)

    定义 数堆名字取了Tree和Heap各一半,即Treap,是二叉搜索树和堆合并构成的数据结构。而堆和二叉搜索树的性...

  • Day1--堆和优先权队列

    ·堆 一、堆的定义: 堆是一颗完全二叉树。 二、分类: 分为最大堆和最小堆。最大堆是树中每个节点的值都大于...

  • 2019-03-24二叉堆

    二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。二叉堆有两种:最大堆和最小堆。最...

  • 【算法】堆排序

    几个概念 堆:堆本质就是一棵完全二叉树。常用的两种堆:最大堆、最小堆。1、最大堆(大顶堆):堆的每个父节点都大于其...

  • 02-13:leetcode重刷5之最大堆/最小堆

    1、最大堆/最小堆结构 (1)最大堆 堆顶元素最大,其他元素都小于等于:堆顶 (2)最小堆 堆顶元素最小,其他元素...

  • 每天一点算法-堆(Day9)

    上一篇介绍了完全二叉树,今天介绍的堆就是一颗完全二叉树,但堆要被放到数组里做实现。 最大堆、最小堆 最小堆(小根堆...

  • 《恋上数据结构与算法一》笔记(十六)堆

    目录 问题思考 Top K问题 堆(Heap) 堆的基本接口设计 二叉堆(Binary Heap) 获取最大值 最...

网友评论

      本文标题:堆, 堆树(最小堆/最大堆) - heap, treap

      本文链接:https://www.haomeiwen.com/subject/snzixctx.html