LeetCode笔记:Biweekly Contest 94
Posted Espresso Macchiato
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode笔记:Biweekly Contest 94相关的知识,希望对你有一定的参考价值。
1. 题目一
给出题目一的试题链接如下:
1. 解题思路
这一题事实上有一点无聊,因为全部的难度事实上都只在读题目上而已,其实核心点就两点:
- 必须从一个1的节点开始,停到一个-1的节点上;
- 路径当中的所有的节点除了首位之外值均为0;
在这种情况下,令路径长度最大化。
因此,我们只需要正反两向各自遍历一下即可。
2. 代码实现
给出python代码实现如下:
class Solution:
def captureForts(self, forts: List[int]) -> int:
res = 0
cnt = 0
have_army = False
for i in forts:
if not have_army:
if i == 1:
have_army = True
else:
if i == 1:
cnt = 0
elif i == 0:
cnt += 1
else:
res = max(res, cnt)
cnt = 0
have_army = False
cnt = 0
have_army = False
for i in forts[::-1]:
if not have_army:
if i == 1:
have_army = True
else:
if i == 1:
cnt = 0
elif i == 0:
cnt += 1
else:
res = max(res, cnt)
cnt = 0
have_army = False
return res
提交代码评测得到:耗时47ms,占用内存14MB。
2. 题目二
给出题目二的试题链接如下:
1. 解题思路
这一题其实就是根据每个学生的report计算一下学生的评价分数,然后排个序取前k个即可。
于是剩下的问题就是如何相对高效的求一下学生们的分数了,而这个其实只需要对positive和negative的词汇做一个hash表就可以相对快速地进行判断了,也不是啥难事。
2. 代码实现
给出python代码实现如下:
class Solution:
def topStudents(self, positive_feedback: List[str], negative_feedback: List[str], report: List[str], student_id: List[int], k: int) -> List[int]:
positive_feedback, negative_feedback = set(positive_feedback), set(negative_feedback)
n = len(student_id)
def get_score(report):
score = 0
for w in report.split():
if w in positive_feedback:
score += 3
elif w in negative_feedback:
score -= 1
return score
score = [(get_score(report[i]), -student_id[i]) for i in range(n)]
score = sorted(score, reverse=True)[:k]
return [-x[1] for x in score]
提交代码评测得到:耗时358ms,占用内存22.7MB。
3. 题目三
给出题目三的试题链接如下:
1. 解题思路
这一题其实非常的简单,就是用二分法找到第一个可以满足的n,使得不小于n的数可以分成两个不重叠的array使得:
- 第一个array包含至少uniqueCnt1个数,且其中的数都不被divisor1整除;
- 第二个array包含至少uniqueCnt2个数,且其中的数都不被divisor2整除。
而要考察这个n能否成立,我们其实还是相当简单可以通过下述方式快速判断的:
- 不小于n的数当中,仅不能被divisor1整除全部归于array1;
- 不小于n的数当中,仅不能被divisor2整除全部归于array2;
- 同时不被divisor1与divisor2整除的数个数大于剩余的坑位即可完成构造。
因此,剩下的问题就是如何求出剩下几个值:
- 不小于n的数当中,仅不能被divisor1整除的数;
- 不小于n的数当中,仅不能被divisor2整除的数;
- 不小于n的数当中,同时不被divisor1与divisor2整除的数;
而这个其实通过容斥原理其实还是非常容易化简为求下列三个数:
- 不小于n的数当中,能被divisor1整除的数,记为s1;
- 不小于n的数当中,能被divisor2整除的数,记为s2;
- 不小于n的数当中,同时能被divisor1与divisor2整除的数,即为s3;
则:
- 同时不被divisor1与divisor2整除的数为:t3 = (n-s1) + (n-s2) + s3 - n
- 仅不能被divisor1整除的数:t1 = n - s1 - t3
- 仅不能被divisor2整除的数:t2 = n - s2 - t3
由此,问题即可求解。
2. 代码实现
给出python代码实现如下:
class Solution:
def minimizeSet(self, divisor1: int, divisor2: int, uniqueCnt1: int, uniqueCnt2: int) -> int:
_lcm = lcm(divisor1, divisor2)
# print(_lcm)
def is_possible(n):
cnt1 = n - n // divisor1
cnt2 = n - n // divisor2
cnt3 = cnt1 + cnt2 + n // _lcm - n
return max(uniqueCnt1 - (cnt1 - cnt3), 0) + max(uniqueCnt2 - (cnt2 - cnt3), 0) <= cnt3
i, j = 0, 10**10
while j-i > 1:
n = (i+j)//2
if is_possible(n):
j = n
else:
i = n
return j
提交代码评测得到:耗时29ms,占用内存13.8MB。
4. 题目四
给出题目四的试题链接如下:
1. 解题思路
这一题思路上来说同样也比较直接,就是求取一下每一个单词的同构数目然后相乘求余即可。
而如何求取每一个单词的同构数目,其实也是一个非常简单的排列组合的题目,假设单词总长为n,包含了m个字符,每个字符的个数为 n m n_m nm,则单词的同构数目即为:
s = n ! Π i = 1 m n i ! s = \\fracn!\\mathop\\Pi\\limits_i=1^mn_i! s=i=1Πmni!n!
由此,问题得解。
2. 代码实现
给出python代码实现如下:
class Solution:
def countAnagrams(self, s: str) -> int:
MOD = 10**9+7
@lru_cache(None)
def count_anagram(w):
n = len(w)
ms = Counter(w).values()
res = math.factorial(n)
for m in ms:
res = res * pow(math.factorial(m), -1, mod=MOD) % MOD
return res
res = 1
for w in s.split():
res = res * count_anagram(w) % MOD
return res
提交代码评测得到:耗时1352ms,占用内存15.6MB。
以上是关于LeetCode笔记:Biweekly Contest 94的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode笔记:Biweekly Contest 79
LeetCode笔记:Biweekly Contest 93
LeetCode笔记:Biweekly Contest 89
LeetCode笔记:Biweekly Contest 69