LeetCode笔记:Biweekly Contest 60
Posted 墨客无言
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode笔记:Biweekly Contest 60相关的知识,希望对你有一定的参考价值。
1. 题目一
给出题目一的试题链接如下:
1. 解题思路
这一题思路挺直接的,就是找到某个元素左侧的元素之和恰好等于右侧的元素之和即可。
而后者则可以通过总的元素之和减去当前元素以及其自身求得。
综上我们就可以快速得到答案。
2. 代码实现
给出python代码实现如下:
class Solution:
def findMiddleIndex(self, nums: List[int]) -> int:
n, tot = len(nums), sum(nums)
s = 0
for i in range(n):
if 2*s == tot-nums[i]:
return i
s += nums[i]
return -1
提交代码评测得到:耗时36ms,占用内存14.3MB。
2. 题目二
给出题目二的试题链接如下:
1. 解题思路
这一题没想到啥特别好的方法,就是暴力地求解。
从左往右,从上往下依次遍历,当找到一个非零的元素,就将其视为一个farmland的左上角,然后找到其右上角,并通过其找到对应的右下角即可确定矩形,然后将这个矩形的元素全部进行修改即可避免重复操作。
2. 代码实现
给出python代码实现如下:
class Solution:
def findFarmland(self, land: List[List[int]]) -> List[List[int]]:
n, m = len(land), len(land[0])
res = []
for i in range(n):
for j in range(m):
if land[i][j] != 1:
continue
c = j
while c < m and land[i][c] == 1:
c += 1
r = i
while r < n and all(x == 1 for x in land[r][j:c]):
r += 1
res.append([i, j, r-1, c-1])
for x in range(i, r):
for y in range(j, c):
land[x][y] = 2
return res
提交代码评测得到:耗时1172ms,占用内存28MB。
3. 题目三
给出题目三的试题链接如下:
1. 解题思路
这一题感觉也没啥trick可言,就是按照题目意思实现出来就行了……
我们记录下给个节点的父节点,子节点以及其本身的状态,然后upgrade操作当中的父节点与子节点的检查以及更新只需要通过迭代就能够完成了。
2. 代码实现
给出python代码实现如下:
class LockingTree:
def __init__(self, parent: List[int]):
self.parent = parent
self.children = defaultdict(list)
for i, p in enumerate(parent):
self.children[p].append(i)
self.status = [0 for _ in range(len(parent))]
return
def lock(self, num: int, user: int) -> bool:
if self.status[num] == 0:
self.status[num] = user
return True
return False
def unlock(self, num: int, user: int) -> bool:
if self.status[num] == user:
self.status[num] = 0
return True
return False
def upgrade(self, num: int, user: int) -> bool:
def has_locked_parent(n):
if n == -1:
return False
return self.status[n] != 0 or has_locked_parent(self.parent[n])
def has_locked_children(n):
if self.children[n] == []:
return self.status[n] != 0
return self.status[n] != 0 or any(has_locked_children(k) for k in self.children[n])
def _upgrade(n):
self.status[n] = 0
for k in self.children[n]:
_upgrade(k)
return
if self.status[num] != 0:
return False
elif has_locked_parent(num):
return False
elif not has_locked_children(num):
return False
self.status[num] = user
for n in self.children[num]:
_upgrade(n)
return True
提交代码评测得到:耗时3486ms,占用内存19.7MB。
4. 题目四
给出题目四的试题链接如下:
1. 解题思路
这一题比想象中简单一些,由于数据只分布在1~30,因此,我们使用一个counter就可能大幅简化数据结构,然后就是考虑数据的选择问题。
显然,1如果存在k个,那么,根据是否包含以及包含多少个1,可以存在 2 k 2^k 2k种选择方式,而对于其他任意一个数,如果这个数可以被某个质数的平方整除,那么这个数无论如何无法被选取;如果这个数x的左右质因子之前都没有被选择过,我么就可以将这个数加入到候选集当中,可选方式有m种,m为数x在整个序列当中存在的次数。
因此,综上,我们就可以快速地通过迭代进行代码实现了。
2. 代码实现
给出python代码实现如下:
class Solution:
def numberOfGoodSubsets(self, nums: List[int]) -> int:
MOD = 10**9+7
primes = [2,3,5,7,11,13,17,19,23,29]
impossible = {4, 8, 12, 16, 20, 24, 28, 9, 18, 27, 25}
cnt = Counter(nums)
ones = 1
for i in range(cnt[1]):
ones = ones * 2 % MOD
status_map = defaultdict(int)
for i in range(2, 31):
if i in impossible:
continue
status = 0
for p in primes:
if i % p == 0:
status = (status << 1) + 1
else:
status = status << 1
status_map[i] = status
@lru_cache(None)
def dp(k, status):
if k > 30:
return 1 if status != 0 else 0
res = dp(k+1, status)
if k not in impossible and status_map[k] & status == 0:
res += cnt[k] * dp(k+1, status ^ status_map[k])
return res % MOD
return (ones * dp(2, 0)) % MOD
提交代码评测得到:耗时2677ms,占用内存65.9MB。
以上是关于LeetCode笔记:Biweekly Contest 60的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode笔记:Biweekly Contest 79
LeetCode笔记:Biweekly Contest 93
LeetCode笔记:Biweekly Contest 89
LeetCode笔记:Biweekly Contest 69