每天一道算法题20

请实现如下结构:
TopRecord {
public TopRecord(int K); 构造时事先指定好K的大小,构造好就固定不动
public void add(String str); 向该结构中加入一个字符串,可以重复加入
public List top();返回之前加入的所有字符串中,词频最大的k个
}
要求:
add方法,复杂度O(logK);
top方法, 复杂度O(K);

这里要维护3个结构,一个是词频表,一个是数据大小为K的小根堆,一个是下标索引表

public static class Node {
    public String str;
    public int times;

    public Node(String s, int t) {
        this.str = s;
        this.times = t;
    }
}

public static class TopRecord {
    private Node[] heap;
    private int heapSize;
    private HashMap strNodeMap;
    private HashMap nodeIndexMap;

    public TopRecord(int K) {
        heap = new Node[K];
        heapSize = 0;
        strNodeMap = new HashMap();
        nodeIndexMap = new HashMap();
    }

    public void add(String str) {
        Node curNode = null;
        int preIndex = -1;
        if (!strNodeMap.containsKey(str)) {
            curNode = new Node(str, 1);
            strNodeMap.put(str, curNode);
            nodeIndexMap.put(curNode, -1);
        } else {
            curNode = strNodeMap.get(str);
            curNode.times++;
            preIndex = nodeIndexMap.get(curNode);
        }

        if (preIndex == -1) {
            if (heapSize == heap.length) {
                if (heap[0].times < curNode.times) {
                    nodeIndexMap.put(heap[0], -1);
                    nodeIndexMap.put(curNode, 0);
                    heap[0] = curNode;
                    heapify(0, heapSize);
                }
            } else {
                nodeIndexMap.put(curNode, heapSize);
                heap[heapSize] = curNode;
                heapInsert(heapSize++);
            }
        } else {
            heapify(preIndex, heapSize);
        }
    }

    private void heapInsert(int index) {
        while(index != 0) {
            int parent = (index - 1)/2;
            if (heap[index].times < heap[parent].times) {
                swap(parent, index);
                index = parent;
            } else {
                break;
            }
        }
    }

    private void heapify(int index, int heapSize) {
        int l = index * 2 + 1;
        int r = index * 2 + 2;
        int smallest = index;
        while(l < heapSize) {
            if (heap[l].times < heap[index].times) {
                smallest = l;
            }

            if (r < heapSize && heap[r].times < heap[smallest].times) {
                smallest = r;
            }

            if (smallest != index) {
                swap(smallest, index);
            } else {
                break;
            }

            int index = smallest;
            l = index * 2 + 1;
            r = index * 2 + 2;
        }
    }


    private void swap(int index1, int index2) {
        nodeIndexMap.put(heap[index1], index2);
        nodeIndexMap.put(heap[index2], index1);
        Node tmp = heap[index];
        heap[index1] = heap[index2];
        heap[index2] = tmp;
    }
}

你可能感兴趣的:(每天一道算法题20)