LeetCode笔记:Weekly Contest 257
Posted 墨客无言
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode笔记:Weekly Contest 257相关的知识,希望对你有一定的参考价值。
1. 题目一
给出题目一的试题链接如下:
1. 解题思路
这一题写的挺丑的,就是4曾循环直接暴力求解……
2. 代码实现
给出python代码实现如下:
class Solution:
def countQuadruplets(self, nums: List[int]) -> int:
# nums = sorted(nums)
n = len(nums)
res = 0
for i in range(n-3):
for j in range(i+1, n-2):
for k in range(j+1, n-1):
s = nums[i] + nums[j] + nums[k]
for l in range(k+1, n):
if nums[l] == s:
res += 1
return res
提交代码评测得到:耗时920ms,占用内存14MB。
2. 题目二
给出题目二的试题链接如下:
1. 解题思路
这一题还是挺巧妙的,关键在于对properties进行重排序,排序时按照x坐标从大到小,然后y坐标从小到大。
那么,我们就可以快速地证明,如果某一个元素前面存在另一个的元素的y坐标大于其本身,那么其对应的x坐标必然也大于它。
综上,这个元素就是一个weak character。
2. 代码实现
由此,我们可以快速地给出我们的python代码实现如下:
class Solution:
def numberOfWeakCharacters(self, properties: List[List[int]]) -> int:
properties = sorted(properties, key=lambda x: (-x[0], x[1]))
n = len(properties)
max_y = properties[0][1]
res = 0
for i in range(1, n):
if properties[i][1] < max_y:
res += 1
max_y = max(max_y, properties[i][1])
return res
提交代码评测得到:耗时2136ms,占用内存67.7MB。
3. 题目三
给出题目三的试题链接如下:
1. 解题思路
这一题一开始审题不清漏看了条件,然后就怎么都搞不定,简直快疯了,后来看别人的解法注意到有条件nextVisit不会大于其本身,顿时就惊了,然后就比较显然了。
因为nextVisit不会超过自身,因此,要想访问下一个房间,就必然有当前房间被访问了偶数次。进而易见,要想访问第i+1个房间,必然有前面i个房间都被访问了偶数次。
由此,我们定义 f ( u ) f(u) f(u)表示第一次到达第i个节点所需的移动次数, g ( i ) g(i) g(i)表示第2次到达第i个节点所需要的次数,则易有递推公式:
{ f ( i + 1 ) = g ( i ) + 1 g ( i + 1 ) = f ( i + 1 ) + 1 + f ( i + 1 ) − f ( n e x t ( i + 1 ) ) \\left\\{ \\begin{aligned} f(i+1) & = g(i) + 1 \\\\ g(i+1) & = f(i+1) + 1 + f(i+1) - f(next(i+1)) \\end{aligned} \\right. {f(i+1)g(i+1)=g(i)+1=f(i+1)+1+f(i+1)−f(next(i+1))
由此,我们就可以快速地得到答案了。
2. 代码实现
给出python代码实现如下:
class Solution:
def firstDayBeenInAllRooms(self, nextVisit: List[int]) -> int:
MOD = 10**9+7
n = len(nextVisit)
f = [0 for i in range(n)]
g = [1 for i in range(n)]
for i in range(1, n):
f[i] = (g[i-1] + 1) % MOD
g[i] = (f[i] + 1 + f[i] - f[nextVisit[i]]) % MOD
return f[n-1]
提交代码评测得到:耗时1228ms,占用内存28.5MB。
4. 题目四
给出题目四的试题链接如下:
1. 解题思路
这一题思路其实挺清楚的,剩下的就是实现了。
思路上来说,显然不互质的两数可以交换位置,那么对于存在公因子的两个数就属于同一个集合,而最终在同一个集合中的数字总是可以通过一系列的互换最终变得有序的。
因此,我们就是要将所有的数字按照公因子进行分组,然后将各自的组进行排序,然后重新放回到原先的序列位置当中,看一下是否整体上最终还是有序的。
而关于上述分组操作,我们可以通过dsu进行实现。
2. 代码实现
综上,我们就可以给出最重的python代码实现如下:
import time
class DSU:
def __init__(self):
self.dsu = {}
def add(self, x):
if x not in self.dsu:
self.dsu[x] = x
return
def find(self, x):
if self.dsu[x] == x:
return x
self.dsu[x] = self.find(self.dsu[x])
return self.dsu[x]
def union(self, x, y):
x = self.find(x)
y = self.find(y)
self.dsu[x] = y
return
class Solution:
def gcdSort(self, nums: List[int]) -> bool:
def get_primes(n):
k = int(math.sqrt(n+1))
res = []
for i in range(2, k+1):
if n == 1:
break
if n % i != 0:
continue
res.append(i)
while n % i == 0:
n = n // i
if n != 1:
res.append(n)
return res
t = time.time()
dsu = DSU()
for n in nums:
primes = get_primes(n)
dsu.add(n)
for k in primes:
dsu.add(k)
dsu.union(n, k)
groups_var = defaultdict(list)
groups_idx = defaultdict(list)
for i, n in enumerate(nums):
groups_idx[dsu.find(n)].append(i)
groups_var[dsu.find(n)].append(n)
fin = []
for k in groups_var.keys():
groups_var[k] = sorted(groups_var[k])
fin.extend([(idx, var) for idx, var in zip(groups_idx[k], groups_var[k])])
fin = sorted(fin, key=lambda x: (x[1], x[0]))
res = all(fin[i][0] == i for i in range(len(nums)))
return res
提交代码评测得到:耗时6880ms,占用内存24.3MB。
以上是关于LeetCode笔记:Weekly Contest 257的主要内容,如果未能解决你的问题,请参考以下文章