leetcode biweekly contest 79
最近几次的双周赛最后一题都比较难,感觉双周赛的题目质量明显好于周赛质量,当然毕竟只是面试题目,感觉模板化很严重。
2283. 判断一个数的数字计数是否等于数位的值
题目
给你一个下标从 0 开始长度为 n 的字符串 num ,它只包含数字。
如果对于 每个 0 <= i < n 的下标 i ,都满足数位 i 在 num 中出现了 num[i] 次,那么请你返回 true ,否则返回 false 。
示例 1:
输入:num = "1210" |
示例 2:
输入:num = "030" |
提示:
n == num.length1 <= n <= 10num只包含数字。
地址
https://leetcode.cn/problems/check-if-number-has-equal-digit-count-and-digit-value/
题意
直接遍历即可
思路
- 直接统计字符出现次数即可,然后依次遍历即可。
- 复杂度分析:
- 时间复杂度:$O(n)$, 其中 $n$ 为数组的长度。
- 空间复杂度:$O(\Sigma)$。
代码
class Solution { |
2284. 最多单词数的发件人
题目
给你一个聊天记录,共包含 n 条信息。给你两个字符串数组 messages 和 senders ,其中 messages[i] 是 senders[i] 发出的一条 信息 。
一条 信息 是若干用单个空格连接的 单词 ,信息开头和结尾不会有多余空格。发件人的 单词计数 是这个发件人总共发出的 单词数 。注意,一个发件人可能会发出多于一条信息。
请你返回发出单词数 最多 的发件人名字。如果有多个发件人发出最多单词数,请你返回 字典序 最大的名字。
注意:
- 字典序里,大写字母小于小写字母。
"Alice"和"alice"是不同的名字。
示例 1:
输入:messages = ["Hello userTwooo","Hi userThree","Wonderful day Alice","Nice day userThree"], senders = ["Alice","userTwo","userThree","Alice"] |
示例 2:
输入:messages = ["How is leetcode for everyone","Leetcode is useful for practice"], senders = ["Bob","Charlie"] |
提示:
n == messages.length == senders.length1 <= n <= 1041 <= messages[i].length <= 1001 <= senders[i].length <= 10messages[i]包含大写字母、小写字母和 ‘ ‘ 。messages[i]中所有单词都由 单个空格 隔开。messages[i]不包含前导和后缀空格。senders[i]只包含大写英文字母和小写英文字母。
地址
https://leetcode.cn/problems/sender-with-largest-word-count
题意
hash统计
思路
- 直接 $hash$ 统计出每个发件人发送的单词数目即可,然后找到最大值即可。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 为字符串的长度。
- 空间复杂度:$O(n)$, 其中 $n$ 为字符串的长度。
代码
class Solution { |
2285. 道路的最大总重要性
题目
给你一个整数 n,表示一个国家里的城市数目。城市编号为 0 到 n - 1。
给你一个二维整数数组 roads ,其中 roads[i] = [ai, bi] 表示城市 ai 和 bi 之间有一条 双向 道路。
你需要给每个城市安排一个从 1 到 n 之间的整数值,且每个值只能被使用 一次 。道路的 重要性 定义为这条道路连接的两座城市数值 之和 。
请你返回在最优安排下,所有道路重要性 之和 最大 为多少。
示例 1:
输入:n = 5, roads = [[0,1],[1,2],[2,3],[0,2],[1,3],[2,4]] |
示例 2:
输入:n = 5, roads = [[0,3],[2,4],[1,3]] |
提示:
2 <= n <= 5 * 1041 <= roads.length <= 5 * 104roads[i].length == 20 <= ai, bi <= n - 1ai != bi
没有重复道路。
地址
https://leetcode.cn/problems/maximum-total-importance-of-roads
题意
贪心算法
思路
- 这个题目感觉就是简单题目了,设每个节点 $i$ 的度为 $i$ 则我们可以知道道路重要性之和为 $\sum_{i=0}^{n-1}(i \times degree[i])$,所以我们优先将最大的编号分配给度最大的节点即可。
- 复杂度分析:
- 时间复杂度:$O(n \log n)$, 其中 $n$ 为节点的数目。
- 空间复杂度:$O(n)$,其中 $n$ 为节点的数目。
代码
class Solution { |
2286. 以组为单位订音乐会的门票
题目
一个音乐会总共有 n 排座位,编号从 0 到 n - 1 ,每一排有 m个座椅,编号为 0 到 m - 1 。你需要设计一个买票系统,针对以下情况进行座位安排:
同一组的
k位观众坐在 同一排座位,且座位连续 。k位观众中 每一位 都有座位坐,但他们 不一定 坐在一起。
由于观众非常挑剔,所以:只有当一个组里所有成员座位的排数都 小于等于
maxRow,这个组才能订座位。每一组的maxRow可能 不同 。如果有多排座位可以选择,优先选择 最小 的排数。如果同一排中有多个座位可以坐,优先选择号码 最小 的。
请你实现BookMyShow类:BookMyShow(int n, int m),初始化对象,n 是排数,m 是每一排的座位数。int[] gather(int k, int maxRow)返回长度为 2 的数组,表示 k 个成员中 第一个座位 的排数和座位编号,这 k 位成员必须坐在 同一排座位,且座位连续 。换言之,返回最小可能的 r 和 c 满足第 r 排中 [c, c + k - 1] 的座位都是空的,且 r <= maxRow 。如果 无法 安排座位,返回 [] 。boolean scatter(int k, int maxRow)如果组里所有 k 个成员 不一定 要坐在一起的前提下,都能在第 0 排到第 maxRow 排之间找到座位,那么请返回 true 。这种情况下,每个成员都优先找排数 最小 ,然后是座位编号最小的座位。如果不能安排所有 k 个成员的座位,请返回 false 。
示例 1:
输入: |
提示:
1 <= n <= 5 * 1041 <= m, k <= 1090 <= maxRow <= n - 1gather和scatter总 调用次数不超过5 * 104次。
地址
https://leetcode.cn/problems/booking-concert-tickets-in-groups
题意
二分查找 + 线段树
思路
- 这个题目确实超纲了,当然也是第一次见到线段树上二分的情况,还是非常不错的题目,线段树上二分这个方法确实太棒了,有许多地方都可以应用这个动态更新和变换的解法。当然题目中最关键的一点需要明白,对于每一排作为,不管如何选择,每一排的座位中一定是前半部分是坐满的,后半部分是全空的,因为题目要求不管是
gather还是scatter操作每次都是贪心的从每一排的最左边的空位置开始的,所以这样一定保证每一排的座位被分成两部分, 前 $i$ 个座位上一定坐满了人,$i+1$ 以后的座位全部是空的。 - 可以参考题解, 所以我们可以设线段树,设区间 $[l,r]$, 我们用 $tsum[l,r]$ 记录区间从 $i$ 排到 $j$ 排的座位空座位数目,$tmin[l,r]$ 记录区间从 $i$ 排到 $j$ 的空座位的最小起点,对于前缀和的 $sum$ 操作很简单,难点在于线段树上的二分:
- 用线段树维护每个区间上的空座位的起点最小值 $ \textit{tmin}$
- 如果当前区间 $\textit{tmin} > m−k $,则此时剩余的座位数位 $m - \textit{tmin} < k$, 肯定无法满足坐满连续的 $k$ 个人;
- 如果当前区间只包含一个元素,则返回该元素的下标;
- 如果左半部分 $\textit{tmin} \le m−k$,说明左区间存在可以连续坐满 $k$ 个人的空座位的排,递归左半部分;
- 否则如果 $\textit{maxRow}$ 在右半部分内,则递归右半部分;
- 否则返回 $0$。
确实非常桥面的线段上二分的解法。
- 复杂度分析:
- 时间复杂度:$\text{gather}$ 的时间复杂度为 $O(\log n)$, 其中 $n$ 为排数,$\text{scatter}$ 的时间复杂度为 $O((n + q)\log n)$。
- 空间复杂度:$O(n)$, 其中 $n$ 为排数。
代码
|
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://mikemeng.org/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿

扫描二维码,分享此文章