leetcode contest 327
2529. 正整数和负整数的最大计数
给你一个按 非递减顺序 排列的数组 nums
,返回正整数数目和负整数数目中的最大值。
- 换句话讲,如果
nums
中正整数的数目是pos
,而负整数的数目是neg
,返回pos
和neg
二者中的最大值。
注意:0
既不是正整数也不是负整数。
示例 1:
输入:nums = [-2,-1,-1,1,2,3] |
示例 2:
输入:nums = [-3,-2,-1,0,0,1,2] |
示例 3:
输入:nums = [5,20,66,1314] |
提示:
1 <= nums.length <= 2000
-2000 <= nums[i] <= 2000
nums
按 非递减顺序 排列。
地址
https://leetcode.cn/problems/maximum-count-of-positive-integer-and-negative-integer/
题意
直接遍历
思路
- 直接统计负数与整数的个数即可。
- 复杂度分析:
- 时间复杂度:$O(n)$。其中 $n$ 表示给定的数组的长度。
- 空间复杂度:$O(1)$。
代码
class Solution { |
2530. 执行 K 次操作后的最大分数
给你一个下标从 0 开始的整数数组 nums
和一个整数 k
。你的 起始分数 为 0
。
在一步 操作 中:
- 选出一个满足
0 <= i < nums.length
的下标i
, - 将你的 分数 增加
nums[i]
,并且 - 将
nums[i]
替换为ceil(nums[i] / 3)
。
返回在 恰好 执行 k
次操作后,你可能获得的最大分数。
向上取整函数 ceil(val)
的结果是大于或等于 val
的最小整数。
示例 1:
输入:nums = [10,10,10,10,10], k = 5 |
示例 2:
输入:nums = [1,10,3,3,3], k = 3 |
提示:
1 <= nums.length, k <= 105
1 <= nums[i] <= 109
地址
https://leetcode.cn/problems/maximal-score-after-applying-k-operations/
题意
直接模拟 + 堆
思路
- 按照题目模拟,我们每次找到数组中的最大元素 $x$,并将 $x$ 变为 $y = \lceil \frac{x}{3} \rceil$,并将 $y$ 再次加入到数组中,上述操作执行 $k$ 次即可。
- 复杂度分析:
- 时间复杂度:$O(n \log n)$,其中 $n$ 为数组中的元素的长度。
- 空间复杂度:$O(n)$。
代码
class Solution { |
2531. 使字符串总不同字符的数目相等
给你两个下标从 0 开始的字符串 word1
和 word2
。
一次 移动 由以下两个步骤组成:
- 选中两个下标
i
和j
,分别满足0 <= i < word1.length
和0 <= j < word2.length
, - 交换
word1[i]
和word2[j]
。
如果可以通过 恰好一次 移动,使 word1
和 word2
中不同字符的数目相等,则返回 true
;否则,返回 false
。
示例 1:
输入:word1 = "ac", word2 = "b" |
示例 2:
输入:word1 = "abcc", word2 = "aab" |
示例 3:
输入:word1 = "abcde", word2 = "fghij" |
提示:
1 <= word1.length, word2.length <= 105
word1
和word2
仅由小写英文字母组成。
地址
https://leetcode.cn/problems/make-number-of-distinct-characters-equal/
题意
直接遍历
思路
- 由于题目给定的元素比较少,我们直接模拟即可,当然枚举分类讨论也可以,但是感觉没有太多必要。由于字符的种类 $|\Sigma| = 26$,所以我们直接用哈希统计并遍历所有可能的交换即可,然后比较字符的种类数目即可。
- 复杂度分析
- 时间复杂度:时间复杂度为 $O(|\Sigma|^3)$,$|\Sigma|$ 表示字符集的大小。
- 空间复杂度:时间复杂度为 $O(|\Sigma|)$。
代码
class Solution { |
2532. 过桥的时间
共有 k
位工人计划将 n
个箱子从旧仓库移动到新仓库。给你两个整数 n
和 k
,以及一个二维整数数组 time
,数组的大小为 k x 4
,其中 time[i] = [leftToRighti, pickOldi, rightToLefti, putNewi]
。
一条河将两座仓库分隔,只能通过一座桥通行。旧仓库位于河的右岸,新仓库在河的左岸。开始时,所有 k
位工人都在桥的左侧等待。为了移动这些箱子,第 i
位工人(下标从 0 开始)可以:
- 从左岸(新仓库)跨过桥到右岸(旧仓库),用时
leftToRighti
分钟。 - 从旧仓库选择一个箱子,并返回到桥边,用时
pickOldi
分钟。不同工人可以同时搬起所选的箱子。 - 从右岸(旧仓库)跨过桥到左岸(新仓库),用时
rightToLefti
分钟。 - 将箱子放入新仓库,并返回到桥边,用时
putNewi
分钟。不同工人可以同时放下所选的箱子。
如果满足下面任一条件,则认为工人 i
的 效率低于 工人 j
:
leftToRighti + rightToLefti > leftToRightj + rightToLeftj
leftToRighti + rightToLefti == leftToRightj + rightToLeftj
且i > j
工人通过桥时需要遵循以下规则:
- 如果工人
x
到达桥边时,工人y
正在过桥,那么工人x
需要在桥边等待。 - 如果没有正在过桥的工人,那么在桥右边等待的工人可以先过桥。如果同时有多个工人在右边等待,那么 效率最低 的工人会先过桥。
- 如果没有正在过桥的工人,且桥右边也没有在等待的工人,同时旧仓库还剩下至少一个箱子需要搬运,此时在桥左边的工人可以过桥。如果同时有多个工人在左边等待,那么 效率最低 的工人会先过桥。
所有 n
个盒子都需要放入新仓库,请你返回最后一个搬运箱子的工人 到达河左岸 的时间。
示例 1:
输入:n = 1, k = 3, time = [[1,1,2,1],[1,1,3,1],[1,1,4,1]] |
示例 2:
输入:n = 3, k = 2, time = [[1,9,1,8],[10,10,10,10]] |
提示:
1 <= n, k <= 104
time.length == k
time[i].length == 4
1 <= leftToRighti, pickOldi, rightToLefti, putNewi <= 1000
地址
https://leetcode.cn/contest/weekly-contest-327/problems/time-to-cross-a-bridge/
题意
直接模拟 + 优先队列
思路
- 题目也没有特别好的思路,只能直接模拟即可,但是题目有几个关键点需要注意:
- 每次无论从左向右过桥还是从右向左过桥,都只能有一个人过桥,此时在遍历时,每次出现一人过桥后,则我们需要立即更新队列的状态,假设当前为第 $i$ 个从右向左过桥,当前时间为 $currTime$,它过桥花费的时间为 $rightToLeft[i]$,则他过完桥后,则当前的时间变为 $currTime + rightToLeft[i]$,此时我们需要将所有进入等待过桥时间小于等于 $currTime + rightToLeft[i]$ 的工人全部加入到队列中,此时选择等待队列中效率最低的工人过桥;
- 题目要求过桥时要在当前等待队列中选择效率最低的工人过桥,此时我们的优先队列的队首元素即为效率最低的工人, 我们每次从队列中取出即可;
- 每次我们将所有完成箱子的工人按照时间的先后顺序进入到过桥的等待序列中,此时优先队列则为小根堆,队首的元素即为完成时间最早的工人;
- 我们每次计数时,如果当前计算有 $n$ 个工人完成了过钱操作,则表明一定存在 $n$ 个工人完成搬运工作;
- 我们还需要统计最后一个工人完成从右向左过桥的时间即为最终的时间;
- 复杂度分析:
- 时间复杂度:$O(k + n \log k)$,其中 $n$ 表示给定的数, $k$ 表示工人的数目。
- 空间复杂度:$O(k)$,$k$ 表示工人的数目。队列中最多存在 $k$ 个工人。
代码
typedef pair<int, int> pii; |
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://whistle-wind.com/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章