leetcode895 最大频次栈 hashmap

本文详细解析了LeetCode上的第895题“最大频次栈”的解决方案,通过使用哈希映射和链表模拟的栈结构来实现O(1)时间复杂度的操作,包括如何维护元素的频率及其对应的栈结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// leetcode895 最大频次栈
// 其实就是每个元素多了一个频次,为了O(1)获取元素频次,有了一个value-Frequency的映射
// 其次,因为同频次下,按照栈的逻辑先进后出, 同频次需要一个栈
// 为了熟悉链表,用的单链表模拟栈,其实可以用现有的stack库
// 每个频次都需要一个栈,即同一个x在多个频次下有多个副本
// 其实也想过像LFU那样,只存储唯一的副本,但是无法保证x在多个频次下的栈的位置,需要记录
// x在每个频次下的栈中位置,这样在删除x时,无法保证O(1)操作
// 另外还需要维护当前结构的元素的最大频次,以便出栈O(1)

class FreqStack {

    int maxFreq;
    HashMap<Integer, Integer> valToFreq;
    HashMap<Integer, LinkedStack> freqTable;

    public FreqStack() {
        valToFreq = new HashMap<>();
        freqTable = new HashMap<>();
        maxFreq = 0;
    }

    public void push(int val) {
        ListNode node = new ListNode(val);
        int freq = 0;
        if (valToFreq.containsKey(val)) { 
            freq = valToFreq.get(val);
            freq++;

        }else {
            freq = 1;
        }

        if (!freqTable.containsKey(freq))
            freqTable.put(freq, new LinkedStack());

        if (maxFreq < freq) // 更新栈最大频次
            maxFreq = freq;

        freqTable.get(freq).addNode(node);
        valToFreq.put(val, freq);
    }

    public int pop() {
        if (maxFreq == 0) // 栈中没有元素
            return -1;
        LinkedStack stack = freqTable.get(maxFreq);
        int freq = maxFreq;
        int val = stack.removeHead();
        if (stack.isEmpty()){ // 最大频次只有一个元素
            freqTable.remove(maxFreq);
            maxFreq--;
        }
        if (maxFreq == 0)
            valToFreq.remove(val);
        else
            valToFreq.put(val, freq - 1);
        return val;
    }
}

class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) {
        this.val = val;
        next = null;
    }
}

class LinkedStack {
    private ListNode head;
    public LinkedStack() {
        head = new ListNode();
        head.next = null;
    }

    public void addNode(ListNode node) {
        node.next = head.next;
        head.next = node;
    }


    public int removeHead(){
        return removeNode(head.next);
    }

    public int removeNode(ListNode node) {
        head.next = node.next;
        return node.val;
    }

    public boolean isEmpty() {
        if (head.next == null)
            return true;
        return false;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值