【LeetCode每日一题合集】2023.9.25-2023.10.1(⭐LFU缓存Java数据流花期内花的数量)

文章目录

460. LFU 缓存⭐(数据结构题)

https://leetcode.cn/problems/lfu-cache/description/?envType=daily-question&envId=2023-09-25

在这里插入图片描述

提示:
1 <= capacity <= 10^4
0 <= key <= 10^5
0 <= value <= 10^9
最多调用 2 * 10^5 次 get 和 put 方法

解法1——平衡树 + 哈希表(TreeSet + HashMap) O ( l o g n ) O(logn) O(logn)

自定义节点维护每个键值对的 time 和 cnt。
用 TreeSet 对节点排序,HashMap 存储 key 和 node 的对应关系。

class LFUCache {int capacity, time;Map<Integer, Node> keyTable;TreeSet<Node> s;public LFUCache(int capacity) {this.capacity = capacity;this.time = 0;keyTable = new  HashMap<>();s = new TreeSet<Node>();}public int get(int key) {if (!keyTable.containsKey(key)) return -1;// 取出旧的Node cache = keyTable.get(key);s.remove(cache);// 修改旧的 并重新放入cache.cnt++;cache.time = time++;s.add(cache);keyTable.put(key, cache);return cache.value;}public void put(int key, int value) {if (!keyTable.containsKey(key)) {if (keyTable.size() == capacity) {// 删除最近最少使用的keyTable.remove(s.first().key);s.remove(s.first());}// 创建新的缓存Node cache = new Node(1, time++, key, value);keyTable.put(key, cache);s.add(cache);} else {Node cache = keyTable.get(key);s.remove(cache);cache.cnt++;cache.time = time++;cache.value = value;s.add(cache);keyTable.put(key, cache);}}
}class Node implements Comparable<Node> {int cnt, time, key, value;Node(int cnt, int time, int key, int value) {this.cnt = cnt;this.time = time;this.key = key;this.value = value;}public boolean equals(Object anObject) {if (this == anObject) return true;if (anObject instanceof Node) {Node rhs = (Node) anObject;return this.cnt == rhs.cnt && this.time == this.time;}return false;}public int compareTo(Node rhs) {return cnt == rhs.cnt? time - rhs.time: cnt - rhs.cnt;}public int hashCode() {return cnt * 1000000007 + time;}
}/*** Your LFUCache object will be instantiated and called as such:* LFUCache obj = new LFUCache(capacity);* int param_1 = obj.get(key);* obj.put(key,value);*/

解法2——双哈希表 + 双向链表 O ( 1 ) O(1) O(1) (LRU缓存的升级版)

一个哈希表存储 key 和 Node 之间的关系。另一个哈希表存储 freq 和 DoublyLinkedList 的对应关系。
每个使用频率对应一个双向链表,双向链表维护了该频次所有节点的先后顺序,头节点是最近被使用的,尾节点是最不常被使用的。(类似LRU缓存那道题)。

同时维护一个变量 minFreq,方便快速确定最低使用的频率。

class LFUCache {int minFreq, capacity;Map<Integer, Node> keyTable;Map<Integer, DoublyLinkedList> freqTable;public LFUCache(int capacity) {this.minFreq = 0;this.capacity = capacity;keyTable = new HashMap<Integer, Node>();freqTable = new HashMap<Integer, DoublyLinkedList>();}public int get(int key) {if (capacity == 0) {return -1;}if (!keyTable.containsKey(key)) {return -1;}Node node = keyTable.get(key);int val = node.val, freq = node.freq;freqTable.get(freq).remove(node);// 如果当前链表为空,我们需要在哈希表中删除,且更新minFreqif (freqTable.get(freq).size == 0) {freqTable.remove(freq);if (minFreq == freq) {minFreq += 1;}}// 插入到 freq + 1 中DoublyLinkedList list = freqTable.getOrDefault(freq + 1, new DoublyLinkedList());list.addFirst(new Node(key, val, freq + 1));freqTable.put(freq + 1, list);keyTable.put(key, freqTable.get(freq + 1).getHead());return val;}public void put(int key, int value) {if (!keyTable.containsKey(key)) {// 缓存已满,需要删除if (keyTable.size() == capacity) {Node node = freqTable.get(minFreq).getTail();keyTable.remove(node.key);freqTable.get(minFreq).remove(node);if (freqTable.get(minFreq).size == 0) {freqTable.remove(minFreq);}}// 创建新节点DoublyLinkedList list = freqTable.getOrDefault(1, new DoublyLinkedList());list.addFirst(new Node(key, value, 1));freqTable.put(1, list);keyTable.put(key, freqTable.get(1).getHead());minFreq = 1;} else {// 与 get 操作基本一致,除了需要更新缓存的值Node node = keyTable.get(key);int freq = node.freq;freqTable.get(freq).remove(node);if (freqTable.get(freq).size == 0) {freqTable.remove(freq);if (minFreq == freq) {minFreq += 1;}}DoublyLinkedList list = freqTable.getOrDefault(freq + 1, new DoublyLinkedList());list.addFirst(new Node(key, value, freq + 1));freqTable.put(freq + 1, list);keyTable.put(key, freqTable.get(freq + 1).getHead());}}
}class Node {int key, val, freq;Node prev, next;Node() {this(-1, -1, 0);}Node(int key, int val, int freq) {this.key = key;this.val = val;this.freq = freq;}
}class DoublyLinkedList {Node dummyHead, dummyTail;int size;DoublyLinkedList() {dummyHead = new Node();dummyTail = new Node();dummyHead.next = dummyTail;dummyTail.prev = dummyHead;size = 0;}public void addFirst(Node node) {Node prevHead = dummyHead.next;node.prev = dummyHead;dummyHead.next = node;node.next = prevHead;prevHead.prev = node;size++;}public void remove(Node node) {Node prev = node.prev, next = node.next;prev.next = next;next.prev = prev;size--;}public Node getHead() {return dummyHead.next;}public Node getTail() {return dummyTail.prev;}
}/*** Your LFUCache object will be instantiated and called as such:* LFUCache obj = new LFUCache(capacity);* int param_1 = obj.get(key);* obj.put(key,value);*/

2582. 递枕头

https://leetcode.cn/problems/pass-the-pillow/?envType=daily-question&envId=2023-09-26
在这里插入图片描述

解法——找数学规律

队列长度是 n,每次循环传递 n - 1 次。
计算传递几次循环,以及最后一次循环完成了几次传递。

class Solution {public int passThePillow(int n, int time) {int x = time / (n - 1), y = time % (n - 1);if (x % 2 == 0) return y + 1;return n - y;}
}

1333. 餐厅过滤器(简单模拟)

https://leetcode.cn/problems/filter-restaurants-by-vegan-friendly-price-and-distance/description/?envType=daily-question&envId=2023-09-27

在这里插入图片描述
提示:
1 <= restaurants.length <= 10^4
restaurants[i].length == 5
1 <= idi, ratingi, pricei, distancei <= 10^5
1 <= maxPrice, maxDistance <= 10^5
veganFriendlyi 和 veganFriendly 的值为 0 或 1 。
所有 idi 各不相同。

写法1——手动模拟

class Solution {public List<Integer> filterRestaurants(int[][] restaurants, int veganFriendly, int maxPrice, int maxDistance) {List<int[]> ans = new ArrayList<>();for (int[] r: restaurants) {if (veganFriendly == 1 && r[2] == 0) continue;if (r[3] <= maxPrice && r[4] <= maxDistance) {ans.add(r);}}Collections.sort(ans, (x, y) -> {if (x[1] != y[1]) return y[1] - x[1];return y[0] - x[0];});List<Integer> res = new ArrayList<>();for (int[] x: ans) res.add(x[0]);return res;}
}

写法2——Java数组流处理⭐

class Solution {public List<Integer> filterRestaurants(int[][] restaurants, int veganFriendly, int maxPrice, int maxDistance) {Stream<int[]> stream = Arrays.stream(restaurants);if (veganFriendly == 1) stream = stream.filter(x -> x[2] == 1);return stream.filter(x -> x[3] <= maxPrice).filter(x -> x[4] <= maxDistance).sorted((x, y) -> x[1] != y[1]? y[1] - x[1]: y[0] - x[0]).map(x -> x[0]).collect(Collectors.toList());}
}

2251. 花期内花的数目⭐

https://leetcode.cn/problems/number-of-flowers-in-full-bloom/description/?envType=daily-question&envId=2023-09-28

在这里插入图片描述

提示:
1 <= flowers.length <= 5 * 10^4
flowers[i].length == 2
1 <= starti <= endi <= 10^9
1 <= people.length <= 5 * 10^4
1 <= people[i] <= 10^9

解法1——差分数组

由于花期的数据范围很大,所以使用哈希表来代替数组存储差分结果。

代码的重点是差分数组的还原过程。

class Solution {public int[] fullBloomFlowers(int[][] flowers, int[] people) {Map<Integer, Integer> m = new HashMap<>();  // diff数组for (int[] f: flowers) {int start = f[0], end = f[1];m.merge(start, 1, Integer::sum);m.merge(end + 1, -1, Integer::sum);}// 取出所有的key,从小到大排序int[] times = m.keySet().stream().mapToInt(Integer::intValue).sorted().toArray();int n = people.length, s = 0;int[] ans = new int[n];Integer[] idx = IntStream.range(0, n).boxed().toArray(Integer[]::new);Arrays.sort(idx, (a, b) -> people[a] - people[b]);// 差分数组的还原过程for (int i = 0, j = 0; i < n; ++i) {while (j < times.length && times[j] <= people[idx[i]]) {s += m.get(times[j++]);}ans[idx[i]] = s;}return ans;}
}

解法2——二分查找

计算出某个人到达之前开花的数量 x 和 花谢的数量 y,那么他对应的答案就是 x - y。这个过程可以用二分查找来做。

class Solution {public int[] fullBloomFlowers(int[][] flowers, int[] people) {int n = people.length, m = flowers.length;int[] ans = new int[n];int[] start = new int[m], end = new int[m];for (int i = 0; i < m; ++i) {start[i] = flowers[i][0];end[i] = flowers[i][1];}Arrays.sort(start);Arrays.sort(end);for (int i = 0; i < n; ++i) ans[i] = op(start, end, people[i]);return ans;}public int op(int[] start, int[] end, int time) {int n = start.length;if (start[0] > time || end[n - 1] < time) return 0;return bs(start, time) - bs(end, time - 1);}public int bs(int[] a, int k) {int l = -1, r = a.length - 1;while (l < r) {int mid = l + r + 1 >> 1;if (a[mid] <= k) l = mid;else r = mid - 1;}return l;}
}

605. 种花问题(贪心)

https://leetcode.cn/problems/can-place-flowers/description/?envType=daily-question&envId=2023-09-29

在这里插入图片描述
能种就种,比较数量。

class Solution {public boolean canPlaceFlowers(int[] flowerbed, int n) {int k = 0, m = flowerbed.length;for (int i = 0; i < m; ++i) {if (flowerbed[i] == 0) {if (i - 1 >= 0 && flowerbed[i - 1] == 1) continue;if (i + 1 < m && flowerbed[i + 1] == 1) continue;;k++;flowerbed[i] = 1;}}return k >= n;}
}

2136. 全部开花的最早一天(贪心)

https://leetcode.cn/problems/earliest-possible-day-of-full-bloom/description/?envType=daily-question&envId=2023-09-30

在这里插入图片描述

先种长的慢的。

提示:
n == plantTime.length == growTime.length
1 <= n <= 10^5
1 <= plantTime[i], growTime[i] <= 10^4

class Solution {public int earliestFullBloom(int[] plantTime, int[] growTime) {Integer[] id = IntStream.range(0, plantTime.length).boxed().toArray(Integer[]::new);Arrays.sort(id, (i, j) -> growTime[j] - growTime[i]);int ans = 0, day = 0;for (int i: id) {day += plantTime[i];ans = Math.max(ans, day + growTime[i]);}return ans;}
}

这里学习到 IntStream 流创建数组的使用方法——Integer[] id = IntStream.range(0, plantTime.length).boxed().toArray(Integer[]::new);

121. 买卖股票的最佳时机(贪心 | DP)

在这里插入图片描述
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/description/?envType=daily-question&envId=2023-10-01

解法1——DP

class Solution {public int maxProfit(int[] prices) {int n = prices.length;int[] sell = new int[n], buy = new int[n];buy[0] = -prices[0];for (int i = 1; i < n; ++i) {buy[i] = Math.max(buy[i - 1], -prices[i]);sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]);}return sell[n - 1];}
}

解法2——贪心

class Solution {public int maxProfit(int[] prices) {int n = prices.length, ans = 0, mn = Integer.MAX_VALUE;for (int price: prices) {mn = Math.min(mn, price);ans = Math.max(ans, price - mn);}return ans;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/195913.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 13 - Media框架(14)- OpenMax(二)

这一节我们将来解析 media.codec 这个 HIDL service 究竟提供了什么服务&#xff0c;服务是如何启动的。 1、main 函数 我们先来看 frameworks/av/services/mediacodec/main_codecservice.cpp&#xff1a; int main(int argc __unused, char** argv) {strcpy(argv[0], "…

丹麦能源袭击预示着更关键的基础设施成为目标

5 月&#xff0c;22 个丹麦能源部门组织在与俄罗斯 Sandworm APT 部分相关的攻击中受到损害。 丹麦关键基础设施安全非营利组织 SektorCERT 的一份新报告描述了不同的攻击者群体利用合勤防火墙设备中的多个关键漏洞&#xff08;包括两个零日漏洞&#xff09;侵入工业机械&…

Shell条件测试练习

1、取出/etc/passwd文件的第6行&#xff1b; [rootshell ~]# head -6 /etc/passwd | tail -1 sync:x:5:0:sync:/sbin:/bin/sync [rootshell ~]# sed -n 6p /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync [rootshell ~]# awk NR6 /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync 2…

Node.js之TCP(net)

Hi I’m Shendi Node.js之TCP&#xff08;net&#xff09; 最近使用Nodejs编写程序&#xff0c;需要用到自己编写的分布式工具&#xff0c;于是需要将Java版的用NodeJs重新写一遍&#xff0c;需要使用到TCP通信&#xff0c;于是在这里记录下Node.js TCP 的使用方法 依赖 需要使…

ADS村田电感.mod(spice netlist文件)和.s2p模型导入与区别

ADS村田电感.mod&#xff08;spice netlist文件&#xff09;和.s2p模型导入与区别 简介环境过程s2pspice netlist&#xff08;.mod文件&#xff09;导入和结果对比 简介 记录了ADS村田电感.mod&#xff08;spice netlist文件&#xff09;和.s2p模型导入与区别 环境 ADS2020 …

python趣味编程-5分钟实现一个俄罗斯方块游戏(含源码、步骤讲解)

Python俄罗斯方块游戏是一款基于GUI的标题匹配益智游戏,非常容易理解和使用。说到游戏玩法,一切都和真实的一样。 用户必须管理俄罗斯方块的随机序列。在这个Python 俄罗斯方块游戏项目中,我将教您如何使用 Python 制作俄罗斯方块游戏。 Python 代码中的俄罗斯方块游戏:项目…

【Highway-env】IntersectionEnv代码阅读

文章目录 主要完成任务代码结构1.action space2.default_config3.reward_agent_rewards_agent_reward_reward_rewards小结 4.terminated & truncated5.reset_make_road_make_vehicles_spawn_vehicle 6.step 主要完成任务 IntersectionEnv继承自AbstractEnv,主要完成以下4个…

vscode设置代码模板

一键生成vue3模板代码 效果演示 输入vue3 显示快捷键 按回车键 一键生成自定义模板 实现方法 进入用户代码片段设置 选择片段语言 vue.json输入自定义的代码片段 prefix是触发的内容&#xff0c;按自己的喜好来就行&#xff1b; body是模板代码&#xff0c;写入自己需要的…

RTMP协议和源码解析

一、背景 实时消息传输协议&#xff08;Real-Time Messaging Protocol&#xff09;是目前直播的主要协议&#xff0c;是Adobe公司为Flash播放器和服务器之间提供音视频数据传输服务而设计的应用层私有协议。RTMP协议是目前各大云厂商直线直播业务所公用的基本直播推拉流协议&a…

letcode::最小栈

最小栈 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶部的元素。…

性能测试学习——项目环境搭建和Jmete学习二

项目环境搭建、Jmeter学习二 环境的部署虚拟机的安装虚拟机中添加项目操作步骤 使用环境的注意事项Jmeter的安装和简单使用Jemter的使用的进阶Jemter元件 Jmeter属性执行顺序和作用域作用域以自定义用户变量和用户参数(前置处理器)为例如何解决用户变量和线程组同级时&#xff…

时间序列预测实战(十七)利用Prophet实现电力负荷长期预测(附代码+数据集+详细讲解)

一、本文介绍 Prophet是一个由Facebook开发的开源工具&#xff0c;用于时间序列预测。这个工具特别适合于具有强季节性影响和多个历史数据季节的业务时间序列数据。Prophet的主要思想是将数据分解为如下三个部分&#xff1a;趋势、季节性、节假日和特殊事件。这个模型非常适合…