2024年4月26日力扣每日一题(1146)

2024-04-28 23:28
文章标签 2024 26 日力 1146 每日

本文主要是介绍2024年4月26日力扣每日一题(1146),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2024年4月26日力扣每日一题(1146)

前言

​ 这道题在做的时候感觉很简单,题意很容易理解,但直接去做直接干爆内存,参考了一下灵神的代码,豁然开朗,觉得这道题很有意思,便想着写篇博客记录一下,自己在算法上的欠缺还很多,如有不足或错误之处还望见谅。

1.快照数组

在这里插入图片描述

​ 首先阅读一下题目,题目要求我们实现一个接口,每调用一次get方法,会更新一下索引index的数据,每调用一次get方法,会返回根据snap_id的数据来返回index的历史数据。

2.思路

​ 看到这道题,我首先想到的就是暴力计算,不停的复制数组,但这种方法,大概率不会通过,不是超时就是爆内存,在最坏的情况下,这道题需要复制50000次长度为50000的数组,这会超出内存限制,这让我头大,没了思路,想到map集合可以根据键值对存储数据,似乎可以用map来实现,但具体该怎么使用,自己没有一个思路,这时候去看了题解,瞻仰了一下灵神的代码题解,感觉豁然开朗,大佬就是大佬,太强了。

3.灵神的代码

class SnapshotArray {// 当前快照编号,初始值为 0private int curSnapId;// 每个 index 的历史修改记录private final Map<Integer, List<int[]>> history = new HashMap<>();public SnapshotArray(int length) {}public void set(int index, int val) {history.computeIfAbsent(index, k -> new ArrayList<>()).add(new int[]{curSnapId, val});}public int snap() {return curSnapId++;}public int get(int index, int snapId) {if (!history.containsKey(index)) {return 0;}List<int[]> h = history.get(index);int j = search(h, snapId);return j < 0 ? 0 : h.get(j)[1];}// 返回最大的下标 i,满足 h[i][0] <= x// 如果不存在则返回 -1private int search(List<int[]> h, int x) {// 开区间 (left, right)int left = -1;int right = h.size();while (left + 1 < right) { // 区间不为空// 循环不变量:// h[left][0] <= x// h[right][1] > xint mid = left + (right - left) / 2;if (h.get(mid)[0] <= x) {left = mid; // 区间缩小为 (mid, right)} else {right = mid; // 区间缩小为 (left, mid)}}// 根据循环不变量,此时 h[left][0] <= x 且 h[left+1][0] = h[right][0] > x// 所以 left 是最大的满足 h[left][0] <= x 的下标// 如果不存在,则 left 为其初始值 -1return left;}
}作者:灵茶山艾府
链接:https://leetcode.cn/problems/snapshot-array/solutions/2756291/ji-lu-xiu-gai-li-shi-ha-xi-biao-er-fen-c-b1sh/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4.自己对这道题的理解

1.computeIfAbsent方法

​ 在看灵神代码时出现了一个陌生的API,看来自己的知识欠缺还比较多,去查了一下这个API的使用方法,简单介绍一下。

computeIfAbsent 是 Java 8 引入的一个非常有用的 Map 接口方法,它允许你根据指定的键来条件性地计算并插入一个值。如果指定的键尚未与值关联(或者映射到 null),则它会使用提供的函数计算一个值,并将其与该键关联。

这是其基本用法:

Map<K, V> map = ...; // 假设你已经有了一个Map  V value = map.computeIfAbsent(key, k -> {  // 在这里,你可以根据键 k 来计算一个值  // 例如,你可能想从数据库或其他数据源获取数据  return computeValue(k);  
});

在这个例子中,key 是你要检查的键,而 k -> computeValue(k) 是一个 Function,它根据键 k 来计算一个值。

  • 如果 map 中已经存在与 key 关联的值(即使该值为 null),那么 computeIfAbsent 将返回该值,并且不会执行提供的函数。
  • 如果 map 中不存在与 key 关联的值,那么 computeIfAbsent 将执行提供的函数,使用其返回的值与 key 关联,并返回该值。

这个方法非常有用,因为它允许你以原子方式执行“如果键不存在则插入”的操作,而无需首先检查键是否存在。这可以简化代码,并减少并发环境中可能发生的竞态条件。

注意:computeIfAbsent 不会替换已经存在的值(即使该值为 null)。如果你需要替换已经存在的值(包括 null),你应该使用 computemerge 方法。

那么在灵神的代码中

 public void set(int index, int val) {history.computeIfAbsent(index, k -> new ArrayList<>()).add(new int[]{curSnapId, val});}

​ 这段代码的意思是,如果键k,没有对应的值,那就新建一个列表,并且在这个列表中,添加一个数组,这个数组的数据包含两个值,一个是当前的快照编号,另一个是当前要设置的值。

2.解题思路

​ 根据灵神的解题思路,每次修改之后,不再重复去复制数组,而是单纯再后面添加一个元素,并且由于每次修改后添加的数据是有序的,在调用get方法时,我们可以使用二分查找来查找相对应的历史版本。

​ 二分查找

​ 这道题的二分查找也是一个比较值得注意的点,自己在写的时候,简单的二分查找难住了我不短的时间。

private int search(List<int[]> l, int x) {  int left = 0;  int right = l.size() - 1;  int result = -1; // 初始化result为-1,表示尚未找到匹配项  while (left <= right) {  int mid = left + (right - left) / 2;  if (l.get(mid)[0] <= x) {  // 如果中间位置的快照ID小于等于x,更新result并继续在右侧搜索,以找到可能的更大快照ID  result = mid;  left = mid + 1;  } else {  // 如果中间位置的快照ID大于x,则在左侧继续搜索  right = mid - 1;  }  }  // 返回不大于x的最大快照ID的索引,如果没有找到则返回-1  return result;  
}

这篇关于2024年4月26日力扣每日一题(1146)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/944536

相关文章

2024年华为OD机试真题-测试用例执行计划-Python-OD统一考试(C卷D卷)

题目描述: 某个产品当前迭代周期内有N个特性( F1,F2,.......FN)需要进行覆盖测试,每个特性都被评估了对应的优先级,特性使用其ID作为下标进行标识。 设计了M个测试用例(T1,T2......,TM ),每个用例对应了一个覆盖特性的集合,测试用例使用其ID作为下标进行标识,测试用例的优先级定义为其覆盖的特性的优先级之和。 在开展测试之前,需要制定测试用例的执行顺序,规则为:优先级大

HCIP-Datacom-ARST自选题库_03_VLAN【26道题】

一、单选题 1.QinQ技术是一项扩展VLAN空间的技术,通过在802.1Q标签报文的基础上再增加一层802.1Q的Tag来达到扩展VLAN空间的功能。下列关于QinQ说法错误的是 灵活QinQ可以根据不同的内层Tag而加上不同的外层Tag,对于用户VLAN的划分更加细致 QinQ使VLAN的数是增加到4095*4095 QinQ技术可以使私网VLAN在公网上透传 基本QinQ是基于接口

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第20课-烟花插件

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第20课-烟花插件 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎(内嵌了three.js编辑器的定制版-支持以第一视角游览3D场馆),可以在浏览器和node.js、deno、electron上运行,它

外卖 点金推广实战课程,2024外卖 点金推广全流程(7节课+资料)

课程内容: 外卖点金推广实操课程 资料 01 1-了解外卖.mp4 02 第一节:点金推广的说明.mp4 03 第二节:如何降低点金推广的成本,mp4 04 第三节:如何计算点金推广的流速,mp4 05 第四节:如何提升点金的精准度,mp4 06 第五节:点金推广实操,mp4 07 点金推广高级教程一定最后看.mp4 网盘自动获取 链接:https://pan.baidu.c

周进院长受邀出席2024第四届屈光手术国际论坛获多项荣誉称号!

周进院长受邀出席2024第四届屈光手术国际论坛获“全国首批EVO+ICL(V5)新技术临床应用专家”等多项荣誉称号! 5月10-12日,由爱尔眼科医院集团主办、长沙爱尔眼科医院协办的2024第四届屈光手术国际论坛(IRSS 2024)在湖南长沙盛大举行。一时间,来自中、美、俄、法、韩、土耳其、爱尔兰等9个国家的近400名眼科行业专家、学者“湘”约聚首,共促屈光手术学科、临床、技术的高质量发展!

5月13日,每日信息差

第一、北京近期发生一起诈骗案件,犯罪分子伪装成宽带维修人员,上门为老人安装 VOIP 设备,以此从事电信诈骗活动。设备安装后,会使家庭网络被用于诈骗,且因设备隐蔽安装在居民家中难以察觉。目前,嫌疑人已被抓获,官方提醒民众若发现家中安装可疑设备应立即报警 第二、苹果即将在 2024 年的 WWDC 活动上发布 iOS 18,其中核心更新将是升级版的 Siri。这个新 Siri 将更加注重对话和多功

快来参加【顶尖赛事】LIC·2024 语言与智能技术竞赛

语言与智能技术竞赛(LIC)是由中国中文信息学会(CIPS)和中国计算机学会(CCF)联合主办,百度公司、中国中文信息学会评测工作委员会和中国计算机学会自然语言处理专委会承办的中文NLP顶级赛事,迄今已举办五届,已成为中文NLP领域内最权威、最热门的赛事之一。     作为名副其实的国民科普文化品牌——《十万个为什么》涵盖了广泛科学领域知识问答,承载着几代人的科学启蒙。     本次20

赶紧收藏!2024 年最常见 100道 Java 基础面试题(四十三)

上一篇地址:赶紧收藏!2024 年最常见 100道 Java 基础面试题(四十二)-CSDN博客 八十五、如何实现跨域? 跨域(Cross-Origin Resource Sharing, CORS)是指在Web开发中,出于安全考虑,浏览器限制了来自与当前网站不同域名、端口或协议的资源请求。跨域问题通常发生在前端需要从不同的源(域名、协议或端口)请求数据时。以下是实现跨域请求的几种常见方法:

【C】每日一题 53 最大子数组和

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 这是一个经典的动态规划问题,可以通过遍历数组并利用动态规划的思想来解决。具体步骤如下: 初始化两个变量 max_sum 和 current_sum,分别用来记录全局最大和以及当前连续子数组的和,初始值都设为第一个元素 nums[0]。从数组的第二个元素

2024审计师报名流程图解❗报名时间汇总❗

2024年审计专业技术资格考试报名正在进行中 🔍审计报名流程 一、考生注册 打开浏览器登录中国人事考试网进行【考生注册】,按照提示认真填写个人注册信息,确保个人信息真实、完整、准确,并上传已处理好的照片。 二、考生报名 1⃣考生登录 2⃣选择考试报名 3⃣选择报考省份 4⃣报考信息确认无误后,保存点击“确认” 5⃣报名信息预览 6⃣报名资格核查 7⃣网上缴费 8⃣准考证下载 🔍报名注意事项 1