每天一道算法題20

請實現(xiàn)如下結(jié)構(gòu):
TopRecord {
public TopRecord(int K); 構(gòu)造時事先指定好K的大小,構(gòu)造好就固定不動
public void add(String str); 向該結(jié)構(gòu)中加入一個字符串,可以重復(fù)加入
public List<String> top();返回之前加入的所有字符串中,詞頻最大的k個
}
要求:
add方法,復(fù)雜度O(logK);
top方法, 復(fù)雜度O(K);

這里要維護3個結(jié)構(gòu),一個是詞頻表,一個是數(shù)據(jù)大小為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<String, Node> strNodeMap;
    private HashMap<Node, Integer> nodeIndexMap;

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

    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;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容