首页 > 其他分享 >【每日一题】快照数组

【每日一题】快照数组

时间:2024-05-03 14:44:31浏览次数:32  
标签:index set 快照 int 每日 数组 snap self

1146. 快照数组

实现支持下列接口的「快照数组」- SnapshotArray:

  • SnapshotArray(int length) - 初始化一个与指定长度相等的 类数组 的数据结构。初始时,每个元素都等于 0
  • void set(index, val) - 会将指定索引 index 处的元素设置为 val
  • int snap() - 获取该数组的快照,并返回快照的编号 snap_id(快照号是调用 snap() 的总次数减去 1)。
  • int get(index, snap_id) - 根据指定的 snap_id 选择快照,并返回该快照指定索引 index 的值。

示例:

输入:["SnapshotArray","set","snap","set","get"]
     [[3],[0,5],[],[0,6],[0,0]]
输出:[null,null,0,null,5]
解释:
SnapshotArray snapshotArr = new SnapshotArray(3); // 初始化一个长度为 3 的快照数组
snapshotArr.set(0,5);  // 令 array[0] = 5
snapshotArr.snap();  // 获取快照,返回 snap_id = 0
snapshotArr.set(0,6);
snapshotArr.get(0,0);  // 获取 snap_id = 0 的快照中 array[0] 的值,返回 5

提示:

  • 1 <= length <= 50000
  • 题目最多进行50000setsnap,和 get的调用 。
  • 0 <= index < length
  • 0 <= snap_id < 我们调用 snap() 的总次数
  • 0 <= val <= 10^9

今天这题看似不难,我分了两天写完的。。一开始简单粗暴法内存超了,又死活不想用二分,搞了各种花样还是有问题,后面干脆二分法结束。。

思路就是对数组中的每个位置i维护一个列表 data[i],其中存储了若干二元组,按照时间顺序记录了每一次对位置i的修改操作。

每次set操作,把当前的快照编号和修改的值作为二元组存在索引对应的列表里,最后get的时候就查找最后一个编号小于等于查询快照号的值。

class SnapshotArray:
    def __init__(self, length: int):
        self.snap_cnt = 0
        self.data = defaultdict(list) # 每个index的历史修改记录

    def set(self, index: int, val: int) -> None:
        self.data[index].append((self.snap_cnt, val))

    def snap(self) -> int:
        self.snap_cnt += 1
        return self.snap_cnt - 1
        

    def get(self, index: int, snap_id: int) -> int:
        # 找到snap_cnt <= snap_id 的最后一条修改记录
        # 等价找到snap_cnt >= snap_id+1 的第一条修改记录的前一条
        i = bisect_left(self.data[index], (snap_id+1,)) - 1
        return self.data[index][i][1] if i >=0 else 0
        

标签:index,set,快照,int,每日,数组,snap,self
From: https://www.cnblogs.com/Aikoin/p/18171202

相关文章

  • 架构每日一学 1:成为一名架构师,你必须具有“战略意图”
    本文首发于公众号:腐烂的橘子前言最近学习了《郭东白的架构课》,受益良多。作为一名普通程序员,有时候不禁想问公司里的架构师大牛是怎么成长的,为什么他可以是一名架构师,而我们只能在公司里写代码做需求?郭在文章中提出了很多超出以往认知的观点,让我重新审视了架构师这个职业。除......
  • mORMot 1.18 第13章 动态数组
    mORMot1.18第13章动态数组众所周知,数组是非常有用的。但在现实生活中,情况是不可预测的,数组的元素数量或大小可能会随着时间的推移而增长。有些语言,如PHP,就使得动态数组的使用变得很简单。在使用mORMot的Delphi中,我们使用类和方法来提供这一功能。首先,让我们声明一个典型的TS......
  • 2024-05-01:用go语言,给定两个长度为偶数n的整数数组nums1和nums2, 分别移除它们各自的一
    2024-05-01:用go语言,给定两个长度为偶数n的整数数组nums1和nums2,分别移除它们各自的一半元素,将剩下的元素合并成集合s。找出集合s中可能包含的最多元素数量。输入:nums1=[1,2,3,4,5,6],nums2=[2,3,2,3,2,3]。输出:5。答案2024-05-01:chatgpt题目来自leetcode3002。大体......
  • 【每日一题】总行驶距离
    2739.总行驶距离卡车有两个油箱。给你两个整数,mainTank表示主油箱中的燃料(以升为单位),additionalTank表示副油箱中的燃料(以升为单位)。该卡车每耗费1升燃料都可以行驶10km。每当主油箱使用了5升燃料时,如果副油箱至少有1升燃料,则会将1升燃料从副油箱转移到主油箱。......
  • 39.C语言数组学习的有关整理
    首先还是关于这两个东西sizeof()用于计算所占空间大小strlen()只用于求字符串长度/***sizeof计算所占空间大小\0也会计算*strlen只能用来求字符串长度直到找到字符串结束标志\0**/chararr1[]={'a','b','c'};//abcchararr2[]="abc";//abc\0......
  • 使用g开头的数组字符串的解析
    在做ofd的文件解析的时候,会遇到带有这种描述的数组"g22.03g31.20.2"。这个字符串通过空格进行分割得到一个["g",2,2.0,3,"g",3,1.2,0.2]这样的数组数据。这个是以g表示一个数组的开头,包含了2个元素,每个元素都是2.0的数组。整个字符串翻译成一个完整的数组就是这样......
  • useEffect中的deps数组经常依赖了好多变量,甚至包括对象,如何避免这样,假如某个变量变化
    避免在useEffect的依赖数组中包含大量变量或对象,可以通过以下几种策略来优化:拆分useEffect:如果不同的副作用依赖于不同的状态或变量,可以将它们拆分为多个useEffect调用。这样每个useEffect只关注自己关心的依赖项,使逻辑更加清晰且易于维护。useEffect(()=>{//仅当a变化......
  • 利用二分法删除数组中元素
    二分法的思想主要是要设定起始值和终点值,计算中值,和给定值进行比较,如果大于给定值,则将中值作为终点值,否则作为起始值,重新计算中值。#include<stdio.h>intmain(){intarray[10]={1,2,3,5,8,15,20,30,100,200};intfirst=0,end=9,middle=(first+end)/2,num,i;s......
  • JavaScript数组
     JavaScript数组数组(Array)是属于内置对象,数组和普通对象的功能类似,都可以用来存储一些值。不同的是:普通对象是使用字符串作为属性名,而数组是使用数字作为索引来操作元素。索引:从0开始的整数就是索引。数组的存储性能比普通对象要好。在实际开发中我们经常使用数组存储......
  • 重新排列数组
    给你一个数组nums,数组中有2n个元素,按[x1,x2,...,xn,y1,y2,...,yn]的格式排列。请你将数组按[x1,y1,x2,y2,...,xn,yn]格式重新排列,返回重排后的数组。我写的:  publicint[]Shuffle(int[]nums,intn){      int[]newNums=newint[2*n];  ......