LeetCode 981, 219, 78

目录

  • 981. 基于时间的键值存储
    • 题目链接
    • 标签
    • 思路
    • 代码
  • 219. 存在重复元素 II
    • 题目链接
    • 标签
    • 思路
    • 代码
  • 78. 子集
    • 题目链接
    • 标签
    • 思路
    • 代码

981. 基于时间的键值存储

题目链接

981. 基于时间的键值存储

标签

数组 二分查找 排序

思路

时间戳根据时间生成,时间越早,则时间戳越小;时间越迟,则时间戳越大。例如 由2000-01-01 00:00:00.000生成的时间戳 小于 由2001-01-01 00:00:00.000生成的时间戳。所以 按照时间先后顺序加入本数据结构的值是 按照时间戳 升序排列 的,所以可以考虑在查找时使用二分查找。

题目对本数据结构的实现作了提示:设计一个基于时间的键值数据结构,该结构可以在不同时间戳存储对应同一个键的多个值,并针对特定时间戳检索键对应的值。这就意味着要使用 Map 作为本数据结构的底层实现,key 为一个字符串,value 为这个字符串对应的 所有字符串及其时间戳组成的 集合。看似 value 也是 Map 类型,其实不然。由于这个集合是有序的,所以可以设计一个类 Pair 当作集合的元素类型,使用 List 来存储,Pair 类包含字符串 String value 及 其时间戳 int timestamp。所以最终存储数据的集合为 Map<String, List<Pair>>

对于 void set(String key, String value, int timestamp),直接获取 key 对应的链表 list,如果没有,则创建一个,然后将新的 pair 放入链表 list

对于 String get(String key, int timestamp),先获取 key 对应的链表 list,如果没有,则返回空字符串 ""。接下来就在链表 list 中使用二分查找查找指定的 timestamp

由于要找到 指定timestamp 或其之前的 最大timestamp 对应的 value,所以使用二分法的 前驱实现,如果对二分法的后继和前驱不熟悉,则可以看这篇文章:算法——二分法。

代码

public class TimeMap {// 对组,存放值的value和timestamp属性private static class Pair {String value;int timestamp;public Pair(String value, int timestamp) {this.value = value;this.timestamp = timestamp;}}private final Map<String, List<Pair>> map = new HashMap<>();public TimeMap() {}public void set(String key, String value, int timestamp) {// 获取key对应的list,如果没有,则新建一个ArrayListList<Pair> list = map.computeIfAbsent(key, k -> new ArrayList<>());list.add(new Pair(value, timestamp)); // 将新值放入key对应的list中}public String get(String key, int timestamp) {List<Pair> list = map.get(key); // 获取key对应的listif (list == null) { // 如果没有return ""; // 则返回空字符串}// 由于要找到 指定timestamp 或其之前的 最大timestamp 对应的value,所以使用二分法的前驱实现int left = 0, right = list.size() - 1;while (left < right) {int mid = left + (right - left + 1 >> 1);if (timestamp < list.get(mid).timestamp) {right = mid - 1;} else {left = mid;}}// 如果能找到比 指定timestamp 小的value,则返回它;否则返回空字符串return list.get(left).timestamp <= timestamp ? list.get(left).value : "";}
}

219. 存在重复元素 II

题目链接

219. 存在重复元素 II

标签

数组 哈希表 滑动窗口

思路

本题就是判断 长度为 k 的区间内是否有重复元素

判重 最常用的就是 哈希表HashSet,每次添加新值前先判断是否存在这个值,如果存在,则满足题目要求,返回true;否则才添加这个值。在 Java 中,可以在 add() 之前先使用 contains() 判断是否存在新值。不过,add() 是有返回值的,即返回是否添加成功,如果添加失败,则是因为有重复值。为了减少API的调用次数,从而减少耗费的时间,不使用 if (contains()) + add() 的组合,而是使用 if (!add()) 的组合。

比较复杂的是 控制区间长度为 k:从头到尾顺序遍历数组,每遍历一个元素都将元素加入 HashSet,则当遍历到索引为 k + 1 的元素时,HashSet 中的元素个数为 k 个,此时就得先去除索引为 i - k - 1 的元素,然后才能将索引为 i 的元素加入 HashSet

代码

class Solution {public boolean containsNearbyDuplicate(int[] nums, int k) {Set<Integer> set = new HashSet<>(); // 存储数字的集合for (int i = 0; i < nums.length; i++) {if (i > k) { // 当遍历到索引为k + 1的元素后,集合的元素个数就等于k了set.remove(nums[i - k - 1]); // 每次都需要去除一个元素}if (!set.add(nums[i])) { // 如果nums[i]添加失败,则说明在集合中存在nums[i]return true; // 返回true}}return false;}
}

78. 子集

题目链接

78. 子集

标签

位运算 数组 回溯

思路

在高中数学中学到过这样的知识:对于一个 n n n 个元素的集合,它的子集共有 2 n 2^n 2n。可以用 排列组合 的思想理解它:子集中的元素是从原集合中选取的,对于这 n n n 个元素中的每一个元素,都有 选取不选取 2 2 2 种行为,共需要选择 n n n 次,所以子集(含空集 ∅ \emptyset ,即不选择任何一个值;也含全集,即选择全部值)共有 2 n 2^n 2n 种情况。

本题就是对选取 n n n 个元素的模拟:

  • 判断是否对所有元素都做了选择,如果是,则将选取的元素作为一个集合放到结果链表中;否则进行下列操作。
  • 选取 这个元素,然后对下一个元素做选择。
  • 然后 不选取 这个元素,然后对下一个元素做选择。

对于使用什么数据结构存储选取的元素,由于需要选取和不选取,即先将某个元素加入集合,然后再把这个元素从集合中删除,这是典型的 先进后出 操作,所以使用 来存储选取的元素。

代码

class Solution {public List<List<Integer>> subsets(int[] nums) {res = new ArrayList<>((int) Math.pow(2, nums.length));dfs(nums, 0);return res;}private List<List<Integer>> res; // 存储结果的集合private final LinkedList<Integer> sub = new LinkedList<>(); // 存储子集元素的栈/*** 对nums进行深度优先搜索* @param nums 待遍历数组* @param curr 当前元素索引*/private void dfs(int[] nums, int curr) {if (curr == nums.length) { // 如果将nums遍历完毕res.add(new ArrayList<>(sub)); // 将栈中的元素全部加入结果集合中return; // 然后返回}// 先选取这个元素,并遍历下一个元素sub.push(nums[curr]);dfs(nums, curr + 1);// 然后不选取这个元素,并遍历下一个元素sub.pop();dfs(nums, curr + 1);}
}

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

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

相关文章

鸿蒙语言基础类库:【@ohos.util (util工具函数)】

util工具函数 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 该模块…

Linux系统之lscpu命令的基本使用

Linux系统之lscpu命令的基本使用 一、lscpu命令介绍二、lscpu命令的使用帮助2.1 命令格式2.2 命令选项2.3 使用帮助 三、lscpu命令的基本使用3.1 查看lscpu版本3.2 直接使用lspcu命令3.3 可解析的格式打印cpu信息3.4 可扩展格式打印cpu信息 四、lscpu命令使用注意事项 一、lscp…

【题目/算法训练】:单调队列单调栈

&#x1f680; 前言&#xff1a; 【算法】单调队列&&单调栈 可以在看完这篇文章后&#xff0c;再来写下面的题目 一、绝对差不超过限制的最长连续子数组 思路&#xff1a; 1&#xff09; 就相当于滑动窗口&#xff0c;维护滑动窗口内的两个值&#xff0c;一个是最大值…

Linux常用选项和指令

目录 Linux指令使用注意 用户创建与删除 ls指令 ls指令介绍 ls常见选项 ls选项组合使用 pwd指令 Linux文件系统结构 多叉树结构文件系统介绍 多叉树结构文件系统的特点 cd指令 绝对路径 相对路径 cd指令介绍 家户目录 最近访问的目录 touch指令 ​编辑mkdir指…

3D模型格式转换工具HOOPS Exchange如何访问产品制造信息(PMI)?

在当今的制造和设计领域&#xff0c;产品制造信息&#xff08;PMI&#xff09;在确保零件和产品满足精确规格方面发挥着至关重要的作用。PMI&#xff0c;特别是几何尺寸和公差&#xff08;GD&T&#xff09;&#xff0c;提供了制造过程中必须遵循的详细指导。 随着技术的进…

保持边界感

人与人相处&#xff0c;如同刺猬抱团取暖&#xff1a;靠得太近&#xff0c;会刺痛对方&#xff1b;离得太远&#xff0c;又无法御寒。很多时候&#xff0c;我们与人相处&#xff0c;不是不懂得亲近&#xff0c;而是不懂得疏远。人与人交往&#xff0c;拥有边界感真的很重要。 …

Grind 75 | 3. merge two sorted lists

Leetcode 21. 合并两个有序链表 题目链接 思路&#xff1a; 和归并排序中 merge 部分一致 两个指针分别指向 2 个链表头每次选小的那个加入 res 中&#xff0c;对应指针后移一位;重复步骤2&#xff0c;直至一个指针到链表末尾将另一个剩余的全部 copy 到 res 中&#xff0c;链…

js ES6 part2

forEach遍历 forEach() 方法用于调用数组的每个元素&#xff0c;并将元素传递给回调函数 主要使用场景&#xff1a; 遍历数组的每个元素 语法 被遍历的数组.forEach(function(当前数组元素&#xff0c;当前元素索引号){ //函数体 }) 1. forEach 主要是遍历数组 2. 参数当前…

Milvus核心组件(1)- Architecture

目录 cluster 模式 数据请求处理流程 总流程 逻辑channel 到物理channel 数据维护流程 cluster 模式 上一篇其实已经说过 standalone 模式&#xff0c;其实集群模式大同小异&#xff0c;只是在不同机子间使用Kafka或者其他消息中间件保证数据及逻辑的一致性。 Log Broker…

Mac上配置多版本JDK

在Mac上配置多版本JDK可以通过以下步骤进行&#xff1a; 1. 下载并安装多个JDK版本 你可以从 Oracle 或 AdoptOpenJDK 下载你需要的JDK版本。安装完成后&#xff0c;这些JDK版本通常会被安装在 /Library/Java/JavaVirtualMachines 目录下。 2. 配置环境变量 你可以通过修改…

Mac 上安转文字转 SQL 利器 WrenAI

WrenAI 是一个开源的 Text-SQL 的工具&#xff0c;通过导入数据库结构&#xff0c;通过提问的方式生成 SQL。本文将讲述如何在 MacOS 上安装 WrenAI。要运行WrenAI&#xff0c;首先需要安装 Docker 桌面版。 下载 WrenAI https://github.com/Canner/WrenAI/releases/tag/0.7.…

中断相关知识

进程上下文&#xff1a; 当一个进程在执行时,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容 一个进程的上下文可以分为三个部分:用户级上下文、寄存器上下文以及系统级上下文。 用户级上下文: 正文、数据、用户堆栈以及共享存储区&#xff1b; 寄存器上下文…

java数组之线性查找、二分法查找

一、线性查找 思想&#xff1a;如果想在一个数组中查找是否有某个元素&#xff0c;最容易想到的办法就是遍历数组&#xff0c;将数组中元素与想要查找的元素逐个对比&#xff0c;如果相等表示找到了&#xff0c;如果不等&#xff0c;则表示没找到。这就是线性查找的思想。 案例…

C++多线程和循环队列

假设我们不使用互斥锁&#xff0c;并且我们在两个线程中分别调用 enqueue 和 dequeue 方法。 #include <iostream> #include <thread>template <typename T> class Queue {private:static constexpr int MAX_SIZE 1000;T items[MAX_SIZE];int front, rear;…

算法导论 总结索引 | 第四部分 第十七章:摊还分析

1、数据结构的一个操作序列中 所执行的 所有操作的平均时间&#xff0c;来评估该操作的代价。摊还分析 不同于平均情况分析&#xff0c;它并不涉及概率&#xff0c;它可以保证最坏情况下每个操作的平均性能 它是一种平均情况下的 性能分析方法&#xff0c;用于 评估一系列操作的…

Java多态练习(2024.7.10)

动物类 package KeepPets20240710;public class Animal {private String color;private int age;public Animal(){}public Animal(String color, int age) {this.color color;this.age age;}public String getColor() {return color;}public void setColor(String color) {t…

开源流程表单设计器都有哪些值得一提的优势?

如果需要提质、增效、降本&#xff0c;不妨来了解下低代码技术平台、开源流程表单设计器的功能和优势特点。想要实现流程化办公&#xff0c;低代码技术平台是助力增效的理想工具。功能灵活、操作方便、好维修、可视化操作等优势都是其深受行业喜爱的优势特点。通过本文&#xf…

Errno2:No such file or directory,在当前文件确实没有该图片,怎么解决?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

常用网络概念

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 ​​ 目录 了解组织 局域网技术 …

高深宽比刻蚀和纳米级图形化推进存储器的路线图

随着市场需求推动存储器技术向更高密度、更优性能、新材料、3D堆栈、高深宽比 &#xff08;HAR&#xff09; 刻蚀和极紫外 &#xff08;EUV&#xff09; 光刻发展&#xff0c;泛林集团正在探索未来三到五年生产可能面临的挑战&#xff0c;以经济的成本为晶圆厂提供解决方案。 …