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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值