【模拟】判断一个数的数字计数是否等于数位的值
题目
给你一个下标从 0 开始长度为 n
的字符串 num
,它只包含数字。
如果对于 每个 0 <= i < n
的下标 i
,都满足数位 i
在 num
中出现了 num[i]
次,那么请你返回 true
,否则返回 false
。
示例 1:
|
|
示例 2:
|
|
提示:
n == num.length
1 <= n <= 10
num
只包含数字。
解题思路
模拟即可
代码
|
|
【模拟】最多单词数的发件人
题目
给你一个聊天记录,共包含 n
条信息。给你两个字符串数组 messages
和 senders
,其中 messages[i]
是 senders[i]
发出的一条 信息 。
一条 信息 是若干用单个空格连接的 单词 ,信息开头和结尾不会有多余空格。发件人的 单词计数 是这个发件人总共发出的 单词数 。注意,一个发件人可能会发出多于一条信息。
请你返回发出单词数 最多 的发件人名字。如果有多个发件人发出最多单词数,请你返回 字典序 最大的名字。
注意:
- 字典序里,大写字母小于小写字母。
"Alice"
和"alice"
是不同的名字。
示例 1:
|
|
示例 2:
|
|
提示:
n == messages.length == senders.length
1 <= n <= 10^4
1 <= messages[i].length <= 100
1 <= senders[i].length <= 10
messages[i]
包含大写字母、小写字母和' '
。messages[i]
中所有单词都由 单个空格 隔开。messages[i]
不包含前导和后缀空格。senders[i]
只包含大写英文字母和小写英文字母。
解题思路
统计每个人发送的单词个数
WA了一发,WA在返回值的初始化上,不能盲目地像整型那样,直接初始化答案为第1个人是不妥的。
代码
|
|
【贪心】道路的最大总重要性
题目
给你一个整数 n
,表示一个国家里的城市数目。城市编号为 0
到 n - 1
。
给你一个二维整数数组 roads
,其中 roads[i] = [ai, bi]
表示城市 ai
和 bi
之间有一条 双向 道路。
你需要给每个城市安排一个从 1
到 n
之间的整数值,且每个值只能被使用 一次 。道路的 重要性 定义为这条道路连接的两座城市数值 之和 。
请你返回在最优安排下,所有道路重要性 之和 最大 为多少。
示例 1:
|
|
示例 2:
|
|
提示:
2 <= n <= 5 * 10^4
1 <= roads.length <= 5 * 10^4
roads[i].length == 2
0 <= ai, bi <= n - 1
ai != bi
- 没有重复道路。
解题思路
显然对邻居数越多的点赋予越重要的值,收益越大
代码
|
|
【线段树好题】以组为单位订音乐会的门票
题目
一个音乐会总共有 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 * 10^4
1 <= m, k <= 10^9
0 <= maxRow <= n - 1
gather
和scatter
总 调用次数不超过5 * 10^4
次。
解题思路
比赛的时候这题一开始一直刷不出来?后面看到题也没有思路。就没去做了。看了题解码了代码,发现真是一道线段树好题。
想到了可能要用线段树,但不知道维护啥,当时没注意到座位排的每一行最左边都是排满的,即不会出现两边坐人,中间有空的情况,所以还是很方便维护的。
即线段树的叶子节点对应的是,第i排座位的使用情况,分析后面操作可知,区间维护总和 和 最大值即可。
题中共有两种操作,gather操作和scatter操作。
(由于写线段树一般都从1开始,所以与题中0开始的计序,有个1的偏移)
对于gather操作,对于区间[1,maxRow+1],在该区间查询是否存在有某一个单点的剩余座位数大于等于k,如果存在,则需要对最左边这样的单点进行更新。这需要维护区间最大值(区间最大剩余座位数)。
对于scatter操作,对于区间[1,maxRow+1],在该区间查询剩余总座位数是否大于等于k,如果满足,则需要从左到右落座,即从最左边开始对若干单点进行更新。这需要维护区间总和(区间剩余座位数的总和)。
|
|
push_up
|
|
更新总和 以及 最大值。
注意此题是用不到区间更新的,所以不需要用懒标记,即不需要push_down。
build
|
|
常规线段树建树。叶子节点对应的是单点,即每一排座位的情况。非叶子节点对应的是一个长度大于1的区间,维护了该区间内剩余座位的总和以及最大值。
gather操作
|
|
这个操作处理题中的gather操作。将区间查询和单点更新操作写到了一块儿。
scatter操作
|
|
这个操作处理题中的scatter操作,也是将查询和单点更新写在了一块儿。
每次可先判断左子树的总剩余座位数够不够,如果够的话,就不用管右子树了,这些人应该全部往左子树坐;如果不够的话,可以求出右子树要坐的人,再将这些人往右子树坐。
代码
|
|