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;}

相关内容

热门资讯

千元户外品牌,一股班味 北京世纪金源,曾经的“亚洲最大购物中心”,最近换了一副面孔。 这里俨然成了一座“户外痛城”。从外面看...
千亿分红如期派发,银行股为何依... 如何穿越周期、构建新的护城河,不仅是对银行战略定力的考验,更是其估值能否真正筑底回升的决定性变量 文...
如何选择广州OPC一人轻资产跨... 当下,出海创业成为不少个体经营者和中小企业拓展市场的选择,其中OPC一人轻资产模式因投入低、灵活性高...
原创 若... 时间来到2026年7月,翻看这半年的账本会发现一件挺矛盾的事,家里餐桌上的菜价、货架上的日用品价格几...
欧美企业掀起向中国AI基础设施... 2026年6月,多家海外企业转向中国AI:加密货币交易平台Coinbase将其定为工程师默认工具,美...
天风·轻纺 | 九部门发文鼓励... 我们认为本次文件或更多从供给侧推动零售业升级,鼓励新型优质零售;从网点布局、产品品质、定价体系,消费...
华夏基金(香港)行政总裁甘添专... 中国基金报记者 叶诗婕 在互联互通机制持续深化、全球资产配置需求蓬勃涌现的当下,香港ETF市场正经历...
华尔街的新策略:剔除马斯克 华尔街正将“剔除马斯克”变为一种交易策略。 随着SpaceX以创纪录速度“闪电入指”,引发被动资金大...
500万人的牵挂,有了暖心答案 大众卫生报·新湖南客户端7月9日讯(通讯员 肖心玥 禹晓东)50多天前,一段重型货车碾压伤患者的急诊...
杨山海:黄金,白银下周有放量上... 杨山海:黄金,白银下周有放量上涨的可能! 趁着周末有空,我给大家好好复盘下上周的黄金、白银行情,...
原创 马... #马斯克再出狂言 #:# 马斯克要让 SpaceX 价值超整个地球 #,马斯克又一次凭借魔幻言论刷屏...
AI存储巨头遭遇冰火两重天:S... 存储巨头SK海力士带着265亿美元的庞大募资计划,强势叩开美国资本市场的大门。7月10日,SK海力士...
为什么基金合同要明确投资限制? 基金合同明确投资限制具有多方面的重要意义,对投资者、基金管理人以及整个金融市场都有着不可忽视的作用。...
基金运作如何影响申赎安排更稳妥... 基金的运作机制与申赎安排之间存在着紧密的联系,合理的申赎安排能够确保基金的平稳运作,同时保障投资者的...
破解市场算法的人:粒子物理学博... 萨米尔·瓦尔马博士(Dr. Samir Varma)是一位非常特殊的交易者。他拥有粒子物理学博士背景...
曙光8000正式落成 中国AI... 上证报中国证券网讯(记者 王乔琪)7月9日至7月11日,光合组织2026智能计算应用大会在郑州举行,...
CEO亲自来华,5年在华酒店近... 台州仙居铂尔曼酒店。源自:企业官网 本报(chinatimes.net.cn)记者张蓓 黄指南 深圳...
MiniMax再跌10%!CE... 瑞财经 严明会7月10日,MiniMax(0100.HK)完成新一轮160亿港币融资。当日早盘,Mi...
原创 中... 新能源越跑越快,镍一下子成了绕不过去的原材料“风口”,可就在全球汽车行业拼新能源的时候, 印尼悄悄收...