• 【LeetCode周赛】第194场周赛


    一、1486. 数组异或操作:

    给你两个整数,n 和 start 。

    数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。

    请返回 nums 中所有元素按位异或(XOR)后得到的结果。

    示例:

    输入:n = 5, start = 0
    输出:8
    解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。
    "^" 为按位异或 XOR 运算符。

    分析:

    ​ 简单的模拟过程。

    代码(Python):

    class Solution:
        def xorOperation(self, n: int, start: int) -> int:
            ans = 0
            for i in range(n):
                cur = start + 2 * i
                ans = ans ^ cur
            return ans
    

    二、1487. 保证文件名唯一

    给你一个长度为 n 的字符串数组 names 。你将会在文件系统中创建 n 个文件夹:在第 i 分钟,新建名为 names[i] 的文件夹。

    由于两个文件 不能 共享相同的文件名,因此如果新建文件夹使用的文件名已经被占用,系统会以(k) 的形式为新文件夹的文件名添加后缀,其中 k 是能保证文件名唯一的 最小正整数

    返回长度为 n 的字符串数组,其中 ans[i] 是创建第 i 个文件夹时系统分配给该文件夹的实际名称。

    示例:

    输入:names = ["pes","fifa","gta","pes(2019)"]
    输出:["pes","fifa","gta","pes(2019)"]
    解释:文件系统将会这样创建文件名:
    "pes" --> 之前未分配,仍为 "pes"
    "fifa" --> 之前未分配,仍为 "fifa"
    "gta" --> 之前未分配,仍为 "gta"
    "pes(2019)" --> 之前未分配,仍为 "pes(2019)"

    输入:names = ["kaido","kaido(1)","kaido","kaido(1)"]
    输出:["kaido","kaido(1)","kaido(2)","kaido(1)(1)"]
    解释:注意,如果含后缀文件名被占用,那么系统也会按规则在名称后添加新的后缀 (k) 。

    分析:

    ​ 当时在做的时候写了几个版本:

    ​ (1):题目理解错误。我直接把所有文件名后面的括号及括号中数字全部去掉。接着利用哈希表存储同名元素个数。但是示例二提示:含后缀文件名被占用,那么还要继续添加新后缀。

    ​ (2):TLE。理解正确,但是

    # ...
    name_set = defaultdict(int)
    for name in names:
        # 如果第一次出现该文件名
        if not name_set[name]:
            ans.append(name)
            name_set[name] += 1
        # 如果已经出现,最重要的部分!
        else:
            times = 0
            new_name = "{name}({times})".format(name=name, times=times)
            while name_set[new_name]:
                times += 1
                new_name = "{name}({times})".format(name=name, times=times)
            ans.append(new_name)
            name_set[new_name] += 1
    # ...
    
    • 当发现该文件名已经被占用,首先添加后缀,如果后缀仍然被占用,则括号中数字不断++。
    • 上面就是题目的大概思路,但是问题在于没有利用Hash表中存储的数字。对上面的代码稍加修改就可以通过。

    代码(Python):

    class Solution:
        def getFolderNames(self, names: List[str]) -> List[str]:
            ans = []
            name_set = defaultdict(int)
            for name in names:
                if not name_set[name]:
                    ans.append(name)
                    name_set[name] += 1
                else:
                    # 非常重要,由于defaultdict(int)默认值为0,而此时直接插入已经失败,说明要添加后缀
                    # 如果此时的name已经带后缀,应该直接加后缀,下标应从1开始
                    if not name_set[name]:
                        name_set[name] = 1
    
                    new_name = "{name}({times})".format(name=name, times=name_set[name])
                    while name_set[new_name]:
                        name_set[name] += 1
                        new_name = "{name}({times})".format(name=name, times=name_set[name])
                    ans.append(new_name)
                    name_set[new_name] += 1
            return ans
    

    三、1488. 避免洪水泛滥

    你的国家有无数个湖泊,所有湖泊一开始都是空的。当第 n 个湖泊下雨的时候,如果第 n 个湖泊是空的,那么它就会装满水,否则这个湖泊会发生洪水。你的目标是避免任意一个湖泊发生洪水。

    给你一个整数数组 rains ,其中:

    • rains[i] > 0 表示第 i 天时,第 rains[i] 个湖泊会下雨。

    • rains[i] == 0 表示第 i 天没有湖泊会下雨,你可以选择 一个 湖泊并 抽干 这个湖泊的水。

    请返回一个数组 ans ,满足:

    • ans.length == rains.length

    • 如果 rains[i] > 0 ,那么ans[i] == -1

    • 如果 rains[i] == 0 ,ans[i] 是你第 i 天选择抽干的湖泊。

    如果有多种可行解,请返回它们中的 任意一个 。如果没办法阻止洪水,请返回一个 空的数组

    请注意,如果你选择抽干一个装满水的湖泊,它会变成一个空的湖泊。但如果你选择抽干一个空的湖泊,那么将无事发生(详情请看示例 4)。

    示例:

    输入:rains = [1,2,3,4]
    输出:[-1,-1,-1,-1]
    解释:第一天后,装满水的湖泊包括 [1]
    第二天后,装满水的湖泊包括 [1,2]
    第三天后,装满水的湖泊包括 [1,2,3]
    第四天后,装满水的湖泊包括 [1,2,3,4]
    没有哪一天你可以抽干任何湖泊的水,也没有湖泊会发生洪水。

    输入:rains = [1,2,0,0,2,1]
    输出:[-1,-1,2,1,-1,-1]
    解释:第一天后,装满水的湖泊包括 [1]
    第二天后,装满水的湖泊包括 [1,2]
    第三天后,我们抽干湖泊 2 。所以剩下装满水的湖泊包括 [1]
    第四天后,我们抽干湖泊 1 。所以暂时没有装满水的湖泊了。
    第五天后,装满水的湖泊包括 [2]。
    第六天后,装满水的湖泊包括 [1,2]。
    可以看出,这个方案下不会有洪水发生。同时, [-1,-1,1,2,-1,-1] 也是另一个可行的没有洪水的方案。

    输入:rains = [1,2,0,1,2]
    输出:[]
    解释:第二天后,装满水的湖泊包括 [1,2]。我们可以在第三天抽干一个湖泊的水。
    但第三天后,湖泊 1 和 2 都会再次下雨,所以不管我们第三天抽干哪个湖泊的水,另一个湖泊都会发生洪水。

    分析:

    ​ 双端队列 + 哈希表。具体代码看了一个大佬的题解,我又补充了一些注释。注释分析的已经很不错了,之后再补充一些分析和总结。

    代码(Python):

    class Solution:
        def avoidFlood(self, rains: List[int]) -> list[int]:
            # 使用deque可以确保日期小的在前面
            lake_to_days = defaultdict(deque)
            for date, lake in enumerate(rains):
                if lake != 0:
                    lake_to_days[lake].append(date)
            q = []
            full = set()
            res = []
            for date, lake in enumerate(rains):
                if lake != 0:
                    # 当前湖已经满了,无法避免洪水
                    if lake in full: 
                        return []
                    else:
                        # 依题意,如果该天下雨,不可以抽水
                        res.append(-1)
                        # 将当前湖加入full
                        full.add(lake)
                        # 左侧的第一个日期就是该日期,所以删除
                        lake_to_days[lake].popleft()
                        # 如果该湖之后还要下雨,将日期加入优先队列中
                        if lake_to_days[lake]:
                            hq.heappush(q, lake_to_days[lake][0])
                else:
                    # 优先队列为空,且根据题目要求rains[i] == 0,需排水,因此随便抽一个湖即可
                    if not q:
                        res.append(1)
                    # 选取优先队列中最小的日期,将在该日期下雨的湖抽干
                    else:
                        date = hq.heappop(q)
                        res.append(rains[date])
                        full.remove(rains[date])
            return res
    

  • 相关阅读:
    一些有意思的网站
    SQLLocalDB 11.0持续报错,这是泥马德什么问题啊!!!
    SystemErrorCodes
    事件查看器事件ID部分说明
    Application.AddMessageFilter(this);
    Provider:SSL提供程序,error:0
    SQL Server的“错误:9004”
    关于TortoiseSVN的一些知识
    progressBar走马灯设置
    2015广州强网杯(Misc)
  • 原文地址:https://www.cnblogs.com/enmac/p/13197582.html
Copyright © 2020-2023  润新知