leetcode 第 175 场周赛 - python 解答

这次周赛有点问题,第三题 5334.推文计数 先是出现了在线测试 500 错误。之后提交的时候有些答案错误的情况,系统会返回一个对不上的输入,导致查找错误很困难,也让人很困惑,但是实际上代码对了应该是能过的,我是比赛后才过的。

5332. 检查整数及其两倍数是否存在

https://leetcode-cn.com/probl...
https://leetcode-cn.com/conte...

解题思路

这题居然错了两次。第一次使用 set,结果无法处理 0 的情况,于是换用了 collections.Counter 因为对于 0 要统计 0 的数量,虽然 0 的 2 倍仍然是 0 本身,但是只有 1 个 0 仍是不行的。

代码

class Solution:
    def checkIfExist(self, arr: List[int]) -> bool:
        import collections
        s = collections.Counter(arr)
        for n in s:
            if n == 0:
                if s[n] > 1: return True
            elif n<<1 in s:
                return True
        return False

5333.制造字母异位词的最小步骤数

https://leetcode-cn.com/conte...
https://leetcode-cn.com/probl...

解题思路

使用两个 Counter 分别统计 s 和 t 中出现的各个字母的数量。

只看 t 中比 s 多的字母,一共多多少,加起来就是答案

代码

class Solution:
    def minSteps(self, s: str, t: str) -> int:
        import collections
        c1 = collections.Counter(s)
        c2 = collections.Counter(t)
        ans = 0
        for c in c2:
            if c not in c1:
                ans += c2[c]
            else:
                if c2[c] > c1[c]:
                    ans += c2[c] - c1[c]
        return ans

1348. 推文计数

https://leetcode-cn.com/probl...
https://leetcode-cn.com/conte...

解题思路

比赛的时候样例返回有问题。

本身不难,维护一个字典,把每个用户的时间放入一个数组,查询时,先排序,然后二分找到起始点,向后遍历,要注意的是,如果后面的时间范围中没有推文,也要往数组里补充相应数量的 0。

代码

import bisect
class TweetCounts:

    def __init__(self):
        self.ul = {}
        
    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.ul: self.ul[tweetName] = []
        self.ul[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        self.ul[tweetName].sort()
        #print(self.ul[tweetName])
        if freq == 'minute':
            f = 60
        elif freq == 'hour':
            f = 3600
        else:
            f = 86400
        b = bisect.bisect(self.ul[tweetName], startTime-1)
        ans = []
        cnt = 0
        limit = startTime + f
        for n in self.ul[tweetName][b:]:
            #print(n)
            if n > endTime:
                ans.append(cnt)
                r = (endTime - limit) // f
                if limit < endTime:
                    ans.append(0)
                if r > 0:
                    ans += [0] * r
                return ans
            if n >= limit:
                # 0-59 60-119
                ans.append(cnt)
                r = (n - limit) // f
                if r > 0:
                    ans += [0] * r
                limit += (r + 1) * f
                cnt = 0
            cnt += 1
        ans.append(cnt)
        if limit < endTime:
            ans.append(0)
        r = (endTime - limit) // f
        #print(r, limit)
        if r > 0:
            ans += [0] * r
        return ans

5335.参加考试的最大学生数

https://leetcode-cn.com/conte...

直接搜索会超时(附超时代码)

可以使用状态压缩 dp

解题思路

seat_map 用一个整数表示一行的状态

line_state 标识任意一行所有可行的座位安排(其实就是没有相邻的)因为单就一行来看,只要没人相邻就 ok

line_state 中任意一个和 seat_map 的任意一行做按位与,看是否变化,就可以知道这一行是否可以这么座(是否会坐到坏座位)

两行之间的是否合法,就是一行右移、左移再和另一行按位与。

本思路参考了排行榜上 leoGW 的代码,思路一致,但是重写了。

代码

class Solution:
    def maxStudents(self, seats: List[List[str]]) -> int:
        n = len(seats)
        m = len(seats[0])
        dp = [[-1] *(1<> 1) & k == 0): # 两行没有斜对角的人
                            dp[i][j] = max(dp[i-1][k] + jn, dp[i][j])
        return max(dp[n-1])

欢迎来我的博客: https://codeplot.top/
我的博客刷题分类:https://codeplot.top/categories/%E5%88%B7%E9%A2%98/

你可能感兴趣的:(python,leetcode,动态规划,位运算)