LeetCode笔记:Weekly Contest 254(补发)

1. 题目一

给出题目一的试题链接如下:

1. 解题思路

这一题没啥,将题目用代码语言翻译一下就完事了……

2. 代码实现

给出python代码实现如下:

class Solution:
    def numOfStrings(self, patterns: List[str], word: str) -> int:
        return len([x for x in patterns if x in word])

提交代码评测得到:耗时36ms,占用内存14.4MB。

2. 题目二

给出题目二的试题链接如下:

1. 解题思路

这一题事实上我们只需要给出一个通用的构造方法即可。

我们首先将全部元素进行排序,然后将其从中截断,然后将前半段依次填入到偶数坐标中,后半段依次填入到奇数坐标当中。

此时,对于任意一个偶数位置上的数字,其前后数字均大于它,因此均值必然大于它;同理,对于任意一个奇数位置上的数字,其前后数字均小于它,因此其均值必然小于它。

综上,构造满足题意。

2. 代码实现

给出python代码实现如下:

class Solution:
    def rearrangeArray(self, nums: List[int]) -> List[int]:
        nums = sorted(nums)
        n, m = len(nums), len(nums) // 2
        res = [0] * n
        for i in range(m):
            res[2*i] = nums[m+i]
            res[2*i+1] = nums[i]
        if n % 2 != 0:
            res[-1] = nums[-1]
        return res

提交代码评测得到:耗时1456ms,占用内存30.7MB。

3. 题目三

给出题目三的试题链接如下:

1. 解题思路

这一题的解题思路其实也简单,就是找到最小乘积时的最终排列,然后计算一下其结果。

易证当所有的数据绝对差被拉开至最大时,可以得到最小的乘积,因此,最终的结果就应该是一 2 p − 1 − 1 2^{p-1}-1 2p11 2 p − 2 2^p-2 2p2 2 p − 1 − 1 2^{p-1}-1 2p11 1 1 1以及一个 2 p − 1 2^p-1 2p1的乘积。

剩下的,我们只需要对其进行一下计算就行了。

而关于这部分的计算,事实上我们也只需要首先计算出 ( 2 p − 2 ) 2 p − 1 (2^p-2)^{2^{p-1}} (2p2)2p1然后在除以一个 2 p − 2 2^p-2 2p2即可。

2. 代码实现

我们给出python代码实现如下:

class Solution:
    def minNonZeroProduct(self, p: int) -> int:
        MOD = 10**9+7
        if p == 1:
            return 1
        
        f = [1] * (p+1)
        for i in range(p):
            f[i+1] = 2*f[i] % MOD
        
        res = f[-1] - 1
        # print(res)
        @lru_cache(None)
        def fn(k):
            if k == 1:
                return (f[p]-2) % MOD
            else:
                return fn(k-1) * fn(k-1) % MOD
        
        return res * fn(p) * pow(f[p]-2, -1, mod=MOD) % MOD

提交代码评测得到:耗时24ms,占用内存14.4MB。

4. 题目四

给出题目四的试题链接如下:

1. 解题思路

这一题一开始没有搞出来,真的挺不应该的,因为就是一个dsu,思路上面是个倒推法,就是反过来整,看什么时候从底部到顶部的路线可以被打通。

而这个就可以用一个常规的dsu算法进行实现了。

2. 代码实现

给出python代码实现如下:

class DSU:
    def __init__(self, row, col):
        self.dsu = {(i, j): (i, j) for i in range(row) for j in range(col)}
        self.dsu["bg"] = "bg"
        self.dsu["ed"] = "ed"
        for j in range(col):
            self.union("bg", (0, j))
            self.union("ed", (row-1, j))
    
    def find(self, p):
        if self.dsu[p] == p:
            return p
        self.dsu[p] = self.find(self.dsu[p])
        return self.dsu[p]
    
    def union(self, p1, p2):
        p1 = self.find(p1)
        p2 = self.find(p2)
        self.dsu[p1] = p2
        return
    
    def can_cross(self):
        return self.find("bg") == self.find("ed")

class Solution:
    def latestDayToCross(self, row: int, col: int, cells: List[List[int]]) -> int:
        n = len(cells)
        dsu = DSU(row, col)
        seen = set()
        for idx, (r, c) in enumerate(cells[::-1]):
            r, c = r-1, c-1
            seen.add((r, c))
            if (r-1, c) in seen:
                dsu.union((r, c), (r-1, c))
            if (r+1, c) in seen:
                dsu.union((r, c), (r+1, c))
            if (r, c-1) in seen:
                dsu.union((r, c), (r, c-1))
            if (r, c+1) in seen:
                dsu.union((r, c), (r, c+1))
            if dsu.can_cross():
                return n-1-idx

提交代码评测得到:耗时2164ms,占用内存26.3MB。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值