Leetcode 第 43 场双周赛题解(Python)

2023-11-15

Leetcode 第 43 场双周赛题解

周赛日期:2020/01/09

题目1:1716. 计算力扣银行的钱  难度: 简单

Hercy 想要为购买第一辆车存钱。他 每天 都往力扣银行里存钱。

最开始,他在周一的时候存入 1 块钱。从周二到周日,他每天都比前一天多存入 1 块钱。在接下来每一个周一,他都会比 前一个周一 多存入 1 块钱。

给你 n ,请你返回在第 n 天结束的时候他在力扣银行总共存了多少块钱。

 

示例 1:

输入:n = 4
输出:10
解释:第 4 天后,总额为 1 + 2 + 3 + 4 = 10 。
示例 2:

输入:n = 10
输出:37
解释:第 10 天后,总额为 (1 + 2 + 3 + 4 + 5 + 6 + 7) + (2 + 3 + 4) = 37 。注意到第二个星期一,Hercy 存入 2 块钱。
示例 3:

输入:n = 20
输出:96
解释:第 20 天后,总额为 (1 + 2 + 3 + 4 + 5 + 6 + 7) + (2 + 3 + 4 + 5 + 6 + 7 + 8) + (3 + 4 + 5 + 6 + 7 + 8) = 96 。
 

提示:

1 <= n <= 1000。

题解:模拟or公式

本题上手题,n不大于1000,可以直接模拟,也可以直接计算一下求和公式,这里给出公式法。

class Solution:
    def totalMoney(self, n: int) -> int:
        times = n // 7
        yu = n % 7
        res = 21 * times + (7 * (1 + times) * times) // 2 # 整周
        res += times * yu + (1 + yu) * yu // 2 # 剩余天数
        return res

题目2:1717. 删除子字符串的最大得分  难度: 中等

给你一个字符串 s 和两个整数 x 和 y 。你可以执行下面两种操作任意次。

删除子字符串 "ab" 并得到 x 分。
比方说,从 "cabxbae" 删除 ab ,得到 "cxbae" 。
删除子字符串"ba" 并得到 y 分。
比方说,从 "cabxbae" 删除 ba ,得到 "cabxe" 。
请返回对 s 字符串执行上面操作若干次能得到的最大得分。

 

示例 1:

输入:s = "cdbcbbaaabab", x = 4, y = 5
输出:19
解释:
- 删除 "cdbcbbaaabab" 中加粗的 "ba" ,得到 s = "cdbcbbaaab" ,加 5 分。
- 删除 "cdbcbbaaab" 中加粗的 "ab" ,得到 s = "cdbcbbaa" ,加 4 分。
- 删除 "cdbcbbaa" 中加粗的 "ba" ,得到 s = "cdbcba" ,加 5 分。
- 删除 "cdbcba" 中加粗的 "ba" ,得到 s = "cdbc" ,加 5 分。
总得分为 5 + 4 + 5 + 5 = 19 。
示例 2:

输入:s = "aabbaaxybbaabb", x = 5, y = 4
输出:20
 

提示:

1 <= s.length <= 105
1 <= x, y <= 104
s 只包含小写英文字母。

题解:贪心

x, y谁大,就先消除完那个字符串,由于考虑时间复杂度,可以使用栈来进行操作,方便回删

class Solution:
    def maximumGain(self, s: str, x: int, y: int) -> int:
        a, b = 'ab', 'ba'
        if x < y: 
            a, b = b, a
            x, y = y, x
        res = 0
        stack = []
        for c in s:
            if stack and stack[-1] == a[0] and c == a[1]:
                stack.pop()
                res += x
            else:
                stack.append(c)
        stack_2 = []
        for c in stack:
            if stack_2 and stack_2[-1] == b[0] and c == b[1]:
                stack_2.pop()
                res += y
            else:
                stack_2.append(c)
        return res

题目3:1718. 构建字典序最大的可行序列  难度: 中等

给你一个整数 n ,请你找到满足下面条件的一个序列:

整数 1 在序列中只出现一次。
2 到 n 之间每个整数都恰好出现两次。
对于每个 2 到 n 之间的整数 i ,两个 i 之间出现的距离恰好为 i 。
序列里面两个数 a[i] 和 a[j] 之间的 距离 ,我们定义为它们下标绝对值之差 |j - i| 。

请你返回满足上述条件中 字典序最大 的序列。题目保证在给定限制条件下,一定存在解。

一个序列 a 被认为比序列 b (两者长度相同)字典序更大的条件是: a 和 b 中第一个不一样的数字处,a 序列的数字比 b 序列的数字大。比方说,[0,1,9,0] 比 [0,1,5,6] 字典序更大,因为第一个不同的位置是第三个数字,且 9 比 5 大。

 

示例 1:

输入:n = 3
输出:[3,1,2,3,2]
解释:[2,3,2,1,3] 也是一个可行的序列,但是 [3,1,2,3,2] 是字典序最大的序列。
示例 2:

输入:n = 5
输出:[5,3,1,4,3,5,2,4,2]
 

提示:

1 <= n <= 20

题解:深度优先搜索+贪心

对于前面的数字,肯定是越大越好,所以我们先把大的数字塞在前面,只要找到一个符合条件且尽量大的数都在前面的序列,就是最大的解。

这里使用深度优先搜索去放每一个位置,每一次尽量放当前能放的数字中的最大的数,通过回溯和剪枝来找到第一个符合要求的答案,找到就直接返回。

class Solution:
    def constructDistancedSequence(self, n: int) -> List[int]:
        res = [0] * (2*n-1) # 返回的数组
        index = 0 # 指针
        st = [False] * (n+1) # 访问状态
        
        def dfs(index, cnt, n):
            if cnt == n: return True # 如果所有数都用过了,说明答案找到
            if index >= 2 * n - 1: return False # 如果指针超过数组长度,未找到答案
            flag = False # 判断是否找到答案
            for i in range(n, 0, -1):
                if st[i]: continue # 访问过则跳到下一个数

                # 找到右边最近没有使用过的地址
                while index < (2 * n - 1) and res[index] != 0: index += 1 
                
                # 如果不是1并且第二个i超出范围或者已经被只能用,则不成立,跳到下一个数字
                if i != 1 and (index + i >= (2 * n - 1) or res[index + i] != 0): continue

                res[index] = i # 加入到数组
                if i != 1: res[index+i] = i # 如果不是1则加第二个
                st[i] = True
                flag = dfs(index+1, cnt+1, n)
                if not flag: 
                    st[i] = False # 恢复
                    res[index] = 0
                    if i != 1: res[index+i] = 0
                else: return flag
            return flag
        
        dfs(0, 0, n)
        return res

题目4:1719. 重构一棵树的方案数  难度: 困难

给你一个数组 pairs ,其中 pairs[i] = [xi, yi] ,并且满足:

pairs 中没有重复元素
xi < yi
令 ways 为满足下面条件的有根树的方案数:

树所包含的所有节点值都在 pairs 中。
一个数对 [xi, yi] 出现在 pairs 中 当且仅当 xi 是 yi 的祖先或者 yi 是 xi 的祖先。
注意:构造出来的树不一定是二叉树。
两棵树被视为不同的方案当存在至少一个节点在两棵树中有不同的父节点。

请你返回:

如果 ways == 0 ,返回 0 。
如果 ways == 1 ,返回 1 。
如果 ways > 1 ,返回 2 。
一棵 有根树 指的是只有一个根节点的树,所有边都是从根往外的方向。

我们称从根到一个节点路径上的任意一个节点(除去节点本身)都是该节点的 祖先 。根节点没有祖先。

 

示例 1:


输入:pairs = [[1,2],[2,3]]
输出:1
解释:如上图所示,有且只有一个符合规定的有根树。
示例 2:


输入:pairs = [[1,2],[2,3],[1,3]]
输出:2
解释:有多个符合规定的有根树,其中三个如上图所示。
示例 3:

输入:pairs = [[1,2],[2,3],[2,4],[1,5]]
输出:0
解释:没有符合规定的有根树。
 

提示:

1 <= pairs.length <= 105
1 <= xi < yi <= 500
pairs 中的元素互不相同。

题解:类拓扑排序+模拟

这题非常难,竞赛中只有不到10个人在规定时间内完成了,考察的知识点非常不明显,很难直接想到一个确切的做法,这里博主总结了一个比较好理解的解法。

首先我们需要理解题意,可以找到以下规律:

  • 如果树存在,那么根节点和其他所有节点必有一个pair,所以根节点的出度为n-1,(由于这里很难判断是入度还是出度,我们直接用关系数(relate)来表示)。
  • 如果两个节点有关系,同时他们的关系数一样,说明这两个点可以互换位置,属于等价关系,这时候如果树存在,则至少有两种方案。
  • 如果x是y的祖先,那么relate[x] >= relate[y], 如果x有分支,y与分支下的节点无法有关系。

找到以上几种规律后,我们可以通过一种关系数大小的方法从上到下构建一棵树,这样的方法有点像拓扑排序。

解法如下:

  1. 首先使用邻接表的方式读入边,同时记录每一个点的关系数relate。
  2. 按照rerate降序排序,获取排序后的节点顺序->sorted_idx。
  3. 判断是否存在一个节点x,relate[x] == n-1,如果不存在说明没有根节点,则没有方案树,返回0。
  4. 判断是否有等价关系的两个点,如果有,同时存在方案,则代表返回值2,将res设为2。
  5. 开始将判断是否存在至少一种树:
    1. 用pre代表当前点的父节点,我们通过不断加入到父节点底下来构建一棵树。
    2. 首先将所有的点都加入到根节点下。
    3. 遍历sorted_idx中的节点x,遍历节点x的所有关系点y,如果y之前没有访问过,则说明relate[y] <= relate[x],那它应该属于x底下,这时候判断它的父节点和x的父节点是否一样,如果不一样说明存在冲突,则无解,返回0,如果一样,则将它纳入x节点麾下。
  6. 最后如果还没返回,说明有解,返回res。

class Solution:
    def checkWays(self, pairs: List[List[int]]) -> int:
        from collections import defaultdict
        adj = defaultdict(list) # 邻接表
        relate = defaultdict(int) # 记录关系数
        for x, y in pairs:
            adj[x].append(y); adj[y].append(x)
            relate[x] += 1; relate[y] += 1
        res = 1
        n = len(adj) # 代表节点个数
        sorted_idx = sorted(relate.keys(), key = lambda x: -relate[x]) # 按照关系数进行排序
        if relate[sorted_idx[0]] != n - 1: return 0 # 如果最大关系数不为n-1,说明无法组成树
        for x, y in pairs:
            if relate[x] == relate[y]: # 如果存在关系数相同,说明他们可以调换位置 
                res = 2
                break
        pre = {}
        visit = set([sorted_idx[0]])

        for x in sorted_idx:
            pre[x] = sorted_idx[0] # 先将所有的点挂在根节点下
        for i in range(1, n):
            cur = sorted_idx[i] # 当前节点idx
            visit.add(cur)
            for v in adj[cur]:
                if v not in visit:
                    if pre[v] != pre[cur]: # 不在同一根下,说明有问题
                        return 0
                    pre[v] = cur # 将该节点纳入自己的麾下
        return res

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Leetcode 第 43 场双周赛题解(Python) 的相关文章

随机推荐

  • Py之pdpbox:深度解析Python数据探索库PDPbox

    Py之pdpbox 深度解析Python数据探索库PDPbox PDPbox是一个基于Python的数据探索工具库 可以帮助用户更好地理解数据特征之间的关系以及其对模型性能的影响 该库提供了多种数据可视化和解释工具 方便用户进行快速实验和分
  • python wheel文件

    wheel介绍 whl文件 WHL file 也称为轮子 wheel 这是用于python分发 distribution 的标准内置包格式 standard built package format 它包含安装所需的所有文件和元数据 met
  • 实证研究的步骤_案例研究法

    案例研究法是实地研究的一种 研究者选择一个或几个场景为对象 系统地收集数据和资料 进行深入地研究 用以探讨某一现象在实际生活环境下的状况 比如民族志研究 扎根理论等 可观察也可仅通过资料分析进行研究 适用条件 当现象与实际环境边界不清而且不
  • 使用httpwebrequest发送数据到网站

    怎样通过HttpWebRequest 发送 POST 请求到一个网页服务器 例如编写个程序实现自动用户登录 自动提交表单数据到网站等 假如某个页面有个如下的表单 Form
  • vue简单实现div滚动触底加载更多数据效果

    vue简单实现div滚动触底加载更多数据效果 1 html div class webTherapyAuditList div里放置一些需要滚动加载的信息 滚动函数通过 scroll触发 div 2 js 获取页面滚动距离 handleSc
  • js 获取tabel Cell 内input 的信息

    1 要建立一个清单 在网页表格内输入信息并可以获取保存 这里只写如何获取table 里单元格里input 或 textarea 的信息 2 html 的代码如下 table tr td r name td td r value1 td td
  • arcgis---填充面要素空洞

    1启动编辑 选中面要素 2构造要素选面 3绘制一个包含空洞的任意多边形 4按住shift 选择合并 属性可选择1 2 5 加载绘图工具 使用矩形工具绘制任意的图形覆盖所有图形 6将图形要素转换成面要素 7分析工具 标识 8数据管理 多部分至
  • ROS Navigation-----map_server简介

    map server包提供了一个map server ROS Node 该node通过ROS Service方式提供地图数据 该包还提供了map saver命令行utility 使用该工具可将动态创建的地图保存成文件 1 Map forma
  • 日常——js

    1 闭包 1 1 概念 闭包指 有权访问另一个函数作用域中变量的函数 1 2 优缺点 优点 闭包函数中的变量不会随着闭包函数销毁而销毁 而是要等到还在使用它的函数销毁时才会销毁 缺点 频繁使用闭包会造成内存泄漏 闭包 会将它的外部函数的作用
  • 如何获取 两个日期之间的 天数

    获取两个日期对应的时间戳 1 然后时间戳的差 24 60 60
  • 最大子序列和及序列起始位置-全负数也适用-O(N)时间复杂度

    有一个很经典的题目 给定一个整数组 求连续子序列的最大和 整数为正 负 0皆有可能 先考整数不是全负的情况 和最大的连续子序列 必然是以一个非负数开头 因为和加上一个负数 和变小 此外 和为负数的连续子序列 也不可能是目标子序列的开头的一段
  • 申请苹果个人开发者账号流程

    因为经常有人问我怎么申请苹果开发者账号 这里记录下来方便使用 准备 1 一个苹果账号 Apple ID 2 一张开通visa或master功能的信用卡 3 身份证正反面照片 4 一部苹果手机 5 一个手机号 申请流程 一 先注册一个苹果账号
  • python报错:ImportError: cannot import name ‘calinski_harabaz_score‘ from ‘sklearn.metrics‘解决方案

    报错 ImportError cannot import name calinski harabaz score from sklearn metrics 解决方案 harabaz 改为harabasz 成功解决
  • idea强制回退gitlab分支代码

    1 如果合并分支出错 执行以下两步操作 1 切换到本地分支 找到要回退到的点 2 找到本地该项目的文件目录 空白处右键选择 git bash here 将本地分支代码强推到远程库 执行命令符 git push f origin develo
  • 1.MySQL数据库的基本操作

    数据库操作过程 1 用户在客户端输入 SQL 2 客户端会把 SQL 通过网络发送给服务器 3 服务器执行这个 SQL 把结果返回给客户端 4 客户端收到结果 显示到界面上 数据库的操作 这里的数据库不是代表一个软件 而是代表一个数据集合
  • Navicat 15安装教程,强烈推荐收藏!

    Navicat是一款轻量级的用于MySQL连接和管理的工具 非常好用 使用起来方便 简洁 下面讲讲其安装的过程 1 进入navicat官网 选择Navicat for MySQL 然后点击进行下载即可 官网连接 http www navic
  • VSCode+Qt+MinGW开发环境搭建

    VSCode Qt MinGW开发环境搭建 概述 VSCode扩展性很强 插件机制让其具备不断演进的潜力 适合作为稳定的开发工具 VSCode Qt开发环境的搭建需要依赖于以下工具 VSCode Qt 其中Qt需要安装MinGW编译工具 V
  • 【python-数据分析】笔记1

    数据库vs 仓库 数据库 gt 业务存储 针对应用 仓库 gt 主题存储 针对分析 数据来源 Kaggle 阿里云天池 在python console输入 import pandas as pd df pd read csv data HR
  • 理解javascript的同步与异步模式

    你可能知道 Javascript语言的执行环境是 单线程 single thread 所谓 单线程 就是指一次只能完成一件任务 如果有多个任务 就必须排队 前面一个任务完成 再执行后面一个任务 以此类推 这种模式的好处是实现起来比较简单 执
  • Leetcode 第 43 场双周赛题解(Python)

    Leetcode 第 43 场双周赛题解 周赛日期 2020 01 09 题目1 1716 计算力扣银行的钱 难度 简单 Hercy 想要为购买第一辆车存钱 他 每天 都往力扣银行里存钱 最开始 他在周一的时候存入 1 块钱 从周二到周日