LeetCode-895. 最大频率栈以及HashMap的存值取值操作
admin
2024-03-04 17:12:06
0

LeetCode-895. 最大频率栈

  • 题目描述
  • 解题思路
  • 代码
  • 思考和普及

题目描述

设计一个类似堆栈的数据结构,将元素推入堆栈,并从堆栈中弹出出现频率最高的元素。
实现 FreqStack 类:
FreqStack() 构造一个空的堆栈。
void push(int val) 将一个整数val压入栈顶。
int pop() 删除并返回堆栈中出现频率最高的元素。
如果出现频率最高的元素不只一个,则移除并返回最接近栈顶的元素。

解题思路

实现使用一个变量maxFreq更新每次操作的最大频次

使用哈希表和栈,建立一个存储val和其对应出现频次的哈希表,在建立一个频次key和当前频次出现有哪些元素value使用栈对出现的频次的元素保存的哈希表

代码

class FreqStack {// key是val,value是val对应的频次private Map freq;// key 存储频次,value是val入队的队列private Map> group;private int maxFreq;public FreqStack() {freq = new HashMap();group = new HashMap>();maxFreq = 0;}public void push(int val) {// freq.get(val) 记录的是val的频率freq.put(val,freq.getOrDefault(val,0)+1);// group.get(频次) 记录的是 频次对应出现的元素,putIfAbsent是key为空就group.putIfAbsent(freq.get(val), new ArrayDeque());group.get(freq.get(val)).push(val);// maxFreq 标记每次最大的频次maxFreq = Math.max(maxFreq,freq.get(val));}public int pop() {int val = group.get(maxFreq).pop();freq.put(val,freq.get(val)-1);// 最大频次的队列不为空,最大频率就始终是keyif (group.get(maxFreq).isEmpty()) {maxFreq--;}return val;}
}

思考和普及

HashMap类是java.util包下,HashMap的类继承了抽象Map的抽象类,实现Map接口,可以克隆复制的接口,序列化接口

public class HashMap extends AbstractMap implements Map, Cloneable, Serializable

HashMap putIfAbsent(),方法会先判断指定的键 key 是否存在,不存在则将键值对插入到 HashMap 中。如果所指定的 key 不在 HashMap 中存在,则返回 null

注意,如果指定 key 之前已经和一个 null 值相关联了 ,则该方法也返回 null,因为 HashMap key允许有且仅有一个为 null

    public V getOrDefault(Object key, V defaultValue) {Node e;return (e = this.getNode(hash(key), key)) == null ? defaultValue : e.value;}public V putIfAbsent(K key, V value) {return this.putVal(hash(key), key, value, true, true);}

HashMap的哈希函数的实现,

    static final int hash(Object key) {int h;return key == null ? 0 : (h = key.hashCode()) ^ h >>> 16;}

HashMapput方法

首次扩容,判断数组是否为空,如果数组为空,则进行第一次扩容

在自定义数组容量公式是 容量大小 = 需要的空间 / 0.75 + 1

第二步,计算索引,通过上面的哈希函数,计算键值对在数组中的索引

第三步,插入元素,如果当前位置元素为null,直接插入;如果当前位置元素不为null,并且key已经存在,则直接覆盖掉value;如果当前位置元素不为null,并且key不存在,就将数据链接到链表的末尾;若链表的长度达到8,链表就转化为红黑树,并且将数据插入到树中

第四步,再次扩容,如果数组元素的个数大于threshold,就再次进行扩容

    private static final long serialVersionUID = 362498820763181265L;static final int DEFAULT_INITIAL_CAPACITY = 16;static final int MAXIMUM_CAPACITY = 1073741824;static final float DEFAULT_LOAD_FACTOR = 0.75F;static final int TREEIFY_THRESHOLD = 8;static final int UNTREEIFY_THRESHOLD = 6;static final int MIN_TREEIFY_CAPACITY = 64;transient Node[] table;transient Set> entrySet;transient int size;transient int modCount;int threshold;final float loadFactor;

HashMapput方法,调用了putVal方法

    public V put(K key, V value) {return this.putVal(hash(key), key, value, false, true);}final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {Node[] tab;int n;if ((tab = this.table) == null || (n = tab.length) == 0) {n = (tab = this.resize()).length;}Object p;int i;if ((p = tab[i = n - 1 & hash]) == null) {tab[i] = this.newNode(hash, key, value, (Node)null);} else {Object e;Object k;if (((Node)p).hash == hash && ((k = ((Node)p).key) == key || key != null && key.equals(k))) {e = p;} else if (p instanceof TreeNode) {e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);} else {int binCount = 0;while(true) {if ((e = ((Node)p).next) == null) {((Node)p).next = this.newNode(hash, key, value, (Node)null);if (binCount >= 7) {this.treeifyBin(tab, hash);}break;}if (((Node)e).hash == hash && ((k = ((Node)e).key) == key || key != null && key.equals(k))) {break;}p = e;++binCount;}}if (e != null) {V oldValue = ((Node)e).value;if (!onlyIfAbsent || oldValue == null) {((Node)e).value = value;}this.afterNodeAccess((Node)e);return oldValue;}}++this.modCount;if (++this.size > this.threshold) {this.resize();}this.afterNodeInsertion(evict);return null;}

HashMapget操作,根据传入的key查询到哈希函数操作之后的节点,判断这个节点是否为null,为空返回null,不为空返回节点值

    public V get(Object key) {Node e;return (e = this.getNode(hash(key), key)) == null ? null : e.value;}final Node getNode(int hash, Object key) {Node[] tab;Node first;int n;if ((tab = this.table) != null && (n = tab.length) > 0 && (first = tab[n - 1 & hash]) != null) {Object k;if (first.hash == hash && ((k = first.key) == key || key != null && key.equals(k))) {return first;}Node e;if ((e = first.next) != null) {if (first instanceof TreeNode) {return ((TreeNode)first).getTreeNode(hash, key);}do {if (e.hash == hash && ((k = e.key) == key || key != null && key.equals(k))) {return e;}} while((e = e.next) != null);}}return null;}

相关内容

热门资讯

华夏幸福继续减持 厦门国际银行... 5月18日,河北金融监管局发布批复显示,同意厦门国际银行股份有限公司受让华夏幸福基业控股股份公司持有...
离境退税2.0版政策上线 境外... 本文转自【央视新闻客户端】; 今天(18日),我国离境退税2.0版政策正式上线,以后境外旅客来华购物...
原创 在... 老周坐在东京中野区那间不大的公寓里,又把账本翻了一遍。手边是厚厚的日元工资条,电脑屏幕上开着国内某二...
探索“筷子夹火箭”的商业航天公... 上证报中国证券网讯 国内唯一“不锈钢箭体+液氧甲烷动力+筷子捕获臂回收”技术路线的商业火箭公司再度融...
5月30日晚8点开启!首次全场... 潮新闻客户端 记者 周夏林 又好又便宜的京东618,今年来得有点“聪明”。 5月18日,京东宣布,2...
2026年太和县黄金回收权威机... “家里压箱底的金项链断了,金戒指戴旧了,想去回收却又担心被压价、被掉包。”这是我在太和县做珠宝行业多...
A股“下半场”怎么走?券商最新... 【导读】券商密集召开中期策略会 中国基金报记者 孙越 临近年中,2026年券商中期策略会正迎来密集召...
爱德泰由董事长白长安夫妇控股9... 瑞财经 吴文婷近日,深圳市爱德泰科技股份有限公司(以下简称“爱德泰”)在港交所递交招股书,中信证券、...
前CIA资助研究员:美寻获4种... 近日,一名曾接受美国中央情报局(CIA)资助的前政府研究员曝出惊人消息,声称美国已从坠毁的不明飞行物...
原创 欧... 2026年5月,全球巧克力设备圈炸开了一口大锅。 一百多年来,生产线上那几根核心精磨辊筒,一直被瑞士...
商务部等六部门:加力扩大入境消... 商务部、财政部、国家税务总局等6部门日前发布《关于加力优化离境退税措施扩大入境消费的通知》,此次政策...
飞天没涨价,但茅台真正的变革,... 2026年5月16日零时整,i茅台App推送了一条公告。 不是限量发售,不是新品上架,是涨价。 四款...
“不含白酒”!消费主题ETF营... 【导读】“不含白酒”成了消费主题ETF的营销新卖点? 见习记者 闫军 近期,有基金公司宣传食品饮料E...
金价又崩了!5月这波下跌,藏着... 昨天看行情的时候,我一度以为自己眼花了。 5月18日亚市早盘,现货黄金伦敦金直接失守4500美元/盎...
拿下百年药企、进军医院市场,广... (本文作者为 牛刀财经NiuDaoCJ,钛媒体经授权发布) 文 | 牛刀财经NiuDaoCJ ...
一心卖车的蔚来,终于被看懂了 作者 | 定焦One 陈颐 中国资本市场对新能源汽车的态度,最近一年发生了转变。 具身智能、飞行汽...
原创 杨... 赚的不多,拿的不少。 作者 | 于婞 编辑丨高岩 来源 | 野马财经 与明星爱人黄圣依再见1年后,“...
历史首次!东莞A股上市公司,市... 据东莞市上市公司协会消息,截至2026年5月15日收盘,东莞64家A股上市公司总市值首次突破万亿元,...
对标行业龙头先导智能,格林晟港... 在锂电制造的中段——从极片到电芯成型的核心环节,有一项设备至关重要:叠片机,它直接决定了电池的能量密...
银行存款大局已定?明后年,存款... 银行存款的大局,已经从“怎么多赚点利息”,变成了“怎么少亏点、别踩坑”。 2025年以来,存款利率一...