[LeetCode周赛复盘] 第 296 场周赛20220605

一、本周周赛总结

  • 几乎全是模拟题,除了第二题是一道同向双指针。
  • 第二次打力扣周赛就ak了,这周的题好水啊。
  • 前排的大佬真就做阅读理解呗,读完题=会了。
    在这里插入图片描述

二、 [Easy] 6090. 极大极小游戏

链接: 6090. 极大极小游戏

1. 题目描述

给你一个下标从 0 开始的整数数组 nums ,其长度是 2 的幂。

对 nums 执行下述算法:

设 n 等于 nums 的长度,如果 n == 1 ,终止 算法过程。否则,创建 一个新的整数数组 newNums ,新数组长度为 n / 2 ,下标从 0 开始。
对于满足 0 <= i < n / 2 的每个 偶数 下标 i ,将 newNums[i] 赋值 为 min(nums[2 * i], nums[2 * i + 1]) 。
对于满足 0 <= i < n / 2 的每个 奇数 下标 i ,将 newNums[i] 赋值 为 max(nums[2 * i], nums[2 * i + 1]) 。
用 newNums 替换 nums 。
从步骤 1 开始 重复 整个过程。
执行算法后,返回 nums 中剩下的那个数字。

2. 思路分析

定级Easy。
按题意模拟即可。

3. 代码实现

class Solution:
    def minMaxGame(self, nums: List[int]) -> int:
        
        def dfs(nums):
            n = len(nums)
            if n == 1:
                return nums[0]
            new_nums = [0] * (n//2)
            for i in range(len(new_nums)):
                if i & 1 ==0:
                    new_nums[i] = min(nums[i*2],nums[i*2+1])
                else:
                    new_nums[i] = max(nums[i*2],nums[i*2+1])
            return dfs(new_nums)
        return dfs(nums)

三、[Medium] 6091. 划分数组使最大差为 K

链接: 6091. 划分数组使最大差为 K

1. 题目描述

给你一个整数数组 nums 和一个整数 k 。你可以将 nums 划分成一个或多个 子序列 ,使 nums 中的每个元素都 恰好 出现在一个子序列中。

在满足每个子序列中最大值和最小值之间的差值最多为 k 的前提下,返回需要划分的 最少 子序列数目。

子序列 本质是一个序列,可以通过删除另一个序列中的某些元素(或者不删除)但不改变剩下元素的顺序得到。

2. 思路分析

定级Medium。
是这次周赛唯一有难度的题。
排序后用同向双指针分组即可。

3. 代码实现

class Solution:
    def partitionArray(self, nums: List[int], k: int) -> int:
        n = len(nums)
        nums.sort()
        ans = 0
        l = r = 0
        while l < n and r < n:
            while r < n and nums[r] - nums[l] <= k:
                r += 1
            ans += 1
            l = r
        return ans

四、[Medium] 6092. 替换数组中的元素

链接: 6092. 替换数组中的元素

1. 题目描述

给你一个下标从 0 开始的数组 nums ,它包含 n 个 互不相同 的正整数。请你对这个数组执行 m 个操作,在第 i 个操作中,你需要将数字 operations[i][0] 替换成 operations[i][1] 。

题目保证在第 i 个操作中:

  • operations[i][0] 在 nums 中存在。
  • operations[i][1] 在 nums 中不存在。
    请你返回执行完所有操作后的数组。

2. 思路分析

定级Medium。
按题意模拟即可,用一个字典记录每个数的下标。
由于题意operations限制,因此数组操作过程中不会出现一个数字同时出现在多个地方。

3. 代码实现

class Solution:
    def arrayChange(self, nums: List[int], operations: List[List[int]]) -> List[int]:
        pos = {v:k for k,v in enumerate(nums)}
        for a,b in operations:
            nums[pos[a]] = b
            pos[b] = pos[a]
        return nums

五、[Hard] 1640. 能否连接形成数组

链接: 1640. 能否连接形成数组

1. 题目描述

请你设计一个带光标的文本编辑器,它可以实现以下功能:

  • 添加:在光标所在处添加文本。
  • 删除:在光标所在处删除文本(模拟键盘的删除键)。
  • 移动:将光标往左或者往右移动。
    当删除文本时,只有光标左边的字符会被删除。光标会留在文本内,也就是说任意时候 0 <= cursor.position <= currentText.length 都成立。

请你实现 TextEditor 类:

  • TextEditor() 用空文本初始化对象。
  • void addText(string text) 将 text 添加到光标所在位置。添加完后光标在 text 的右边。
  • int deleteText(int k) 删除光标左边 k 个字符。返回实际删除的字符数目。
  • string cursorLeft(int k) 将光标向左移动 k 次。返回移动后光标左边 min(10, len) 个字符,其中 len 是光标左边的字符数目。
  • string cursorRight(int k) 将光标向右移动 k 次。返回移动后光标左边 min(10, len) 个字符,其中 len 是光标左边的字符数目。

2. 思路分析

定级Hard
然而是纯模拟题,不管是删除还是移动,提前判断是否越界,得出实际移动光标步数即可。

  • 比赛时候看数据量小模拟过了,实际应该用两个栈对倒。

3. 代码实现

模拟

class TextEditor:

    def __init__(self):
        self.s = ''
        self.cursor = 0

    def addText(self, text: str) -> None:
        s=self.s
        cursor =self.cursor
        self.s = s[:cursor] + text + s[cursor:]
        self.cursor += len(text)

    def deleteText(self, k: int) -> int:        
        s=self.s
        cursor =self.cursor
        right = s[cursor:]
        k = min(k,cursor)
        self.cursor -= k        
        left = s[:self.cursor]
        self.s = left+right
        return k        

    def cursorLeft(self, k: int) -> str: 
        s=self.s
        cursor =self.cursor
        k = min(k,cursor)
        self.cursor -= k
        return s[max(0,self.cursor-10):self.cursor]

    def cursorRight(self, k: int) -> str:
        s=self.s
        cursor =self.cursor
        k = min(k,len(s)-cursor)
        self.cursor += k
        return s[max(0,self.cursor-10):self.cursor]


# Your TextEditor object will be instantiated and called as such:
# obj = TextEditor()
# obj.addText(text)
# param_2 = obj.deleteText(k)
# param_3 = obj.cursorLeft(k)
# param_4 = obj.cursorRight(k)

class TextEditor:

    def __init__(self):
        self.left = []  # 两个栈
        self.right = []


    def addText(self, text: str) -> None:
        for c in text:
            self.left.append(c)



    def deleteText(self, k: int) -> int:
        ans = 0
        while self.left and k:
            self.left.pop()
            ans += 1
            k -= 1
        return ans


    def cursorLeft(self, k: int) -> str:
        while self.left and k:
            self.right.append(self.left.pop())
            k-= 1
        if len(self.left) >= 10:
            return ''.join(self.left[-10:])
        else:
            return ''.join(self.left)


    def cursorRight(self, k: int) -> str:
        while self.right and k:
            self.left.append(self.right.pop())
            k-=1
        if len(self.left) >= 10:
            return ''.join(self.left[-10:])
        else:
            return ''.join(self.left)

六、参考链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值