zoukankan      html  css  js  c++  java
  • [Leetcode Weekly Contest]182

    链接:LeetCode

    [Leetcode]1394. 找出数组中的幸运数

    在整数数组中,如果一个整数的出现频次和它的数值大小相等,我们就称这个整数为「幸运数」。
    给你一个整数数组 arr,请你从中找出并返回一个幸运数。

    • 如果数组中存在多个幸运数,只需返回 最大 的那个。
    • 如果数组中不含幸运数,则返回 -1 。

    字典不解释。

    import collections
    class Solution:
        def findLucky(self, arr: List[int]) -> int:
            count = collections.Counter(arr)
            res = -1
            for key in set(arr):
                if key == count[key]:
                    res = max(res,key)
            return res
    

    [Leetcode]1395. 统计作战单位数

    每 3 个士兵可以组成一个作战单位,分组规则如下:
    从队伍中选出下标分别为 i、j、k 的 3 名士兵,他们的评分分别为 (rating[i])(rating[j])(rating[k])
    作战单位需满足:(rating[i] < rating[j] < rating[k])或者(rating[i] > rating[j] > rating[k]),其中$ 0 <= i < j < k < n$
    请你返回按上述条件可以组建的作战单位数量。每个士兵都可以是多个作战单位的一部分。

    一个通用的想法是,是以某个位置作为固定数,比较两侧满足升序或者降序的士兵的个数,相乘相加即可。在寻找两侧比其大/小的数,可以采用遍历或者线段树的方法。

    class Solution:
        def numTeams(self, rating: List[int]) -> int:
            return self.getNum(rating)+self.getNum(rating[::-1])
    
        # 左小右大
        def getNum(self,nums):
            left = [0 for i in range(len(nums))]
            right = [0 for i in range(len(nums))]
            for i in range(len(nums)):
                for j in range(i):
                    if nums[j] < nums[i]:
                        left[i] += 1
                for j in range(i+1,len(nums)):
                    if nums[j] > nums[i]:
                        right[i] += 1
            res = 0
            for i in range(len(nums)):
                res += left[i] * right[i]
            return res
    

    [Leetcode]1396. 设计地铁系统

    请你实现一个类 UndergroundSystem ,它支持以下 3 种方法:
    1. checkIn(int id, string stationName, int t)
    编号为 id 的乘客在 t 时刻进入地铁站 stationName 。
    一个乘客在同一时间只能在一个地铁站进入或者离开。
    2. checkOut(int id, string stationName, int t)
    编号为 id 的乘客在 t 时刻离开地铁站 stationName 。
    3. getAverageTime(string startStation, string endStation)

    • 返回从地铁站 startStation 到地铁站 endStation 的平均花费时间。
    • 平均时间计算的行程包括当前为止所有从 startStation 直接到达 endStation 的行程。
    • 调用 getAverageTime 时,询问的路线至少包含一趟行程。

    你可以假设所有对 checkIn 和 checkOut 的调用都是符合逻辑的。也就是说,如果一个顾客在 t1 时刻到达某个地铁站,那么他离开的时间 t2 一定满足 t2 > t1 。所有的事件都按时间顺序给出。

    使用字典保存信息,在查询平均时间时,只需要查询两个车站,得到总时间,和总次数

    class UndergroundSystem:
        def __init__(self):
            self.ids = {}
            self.underground = {}
    
        def checkIn(self, id: int, stationName: str, t: int) -> None:
            self.ids[id] = [stationName,t]
    
        def checkOut(self, id: int, stationName: str, t: int) -> None:
            start_stationName,start_time = self.ids[id]
            check_stationName = start_stationName+stationName
            pay_time = t-start_time
            if check_stationName not in self.underground:
                self.underground[check_stationName] = [1,pay_time]
            else:
                self.underground[check_stationName][0] += 1
                self.underground[check_stationName][1] += pay_time
    
    
        def getAverageTime(self, startStation: str, endStation: str) -> float:
            times,time = self.underground[startStation+endStation]
            return time/times
    
    
    
    # Your UndergroundSystem object will be instantiated and called as such:
    # obj = UndergroundSystem()
    # obj.checkIn(id,stationName,t)
    # obj.checkOut(id,stationName,t)
    # param_3 = obj.getAverageTime(startStation,endStation)
    

    [Leetcode]1397. 找到所有好字符串

    给你两个长度为 n 的字符串 s1 和 s2 ,以及一个字符串 evil 。请你返回 好字符串 的数目。
    好字符串 的定义为:它的长度为 n ,字典序大于等于 s1 ,字典序小于等于 s2 ,且不包含 evil 为子字符串。
    由于答案可能很大,请你返回答案对(10^9 + 7)取余的结果。
    示例 1:
    输入:n = 2, s1 = "aa", s2 = "da", evil = "b"
    输出:51
    解释:总共有 25 个以 'a' 开头的好字符串:"aa","ac","ad",...,"az"。还有 25 个以 'c' 开头的好字符串:"ca","cc","cd",...,"cz"。最后,还有一个以 'd' 开头的好字符串:"da"。
    示例 2:
    输入:n = 8, s1 = "leetcode", s2 = "leetgoes", evil = "leet"
    输出:0
    解释:所有字典序大于等于 s1 且小于等于 s2 的字符串都以 evil 字符串 "leet" 开头。所以没有好字符串。
    示例 3:
    输入:n = 2, s1 = "gx", s2 = "gz", evil = "x"
    输出:2

    这道题是本周的压轴题,也是我第一次接触这种题型,收获很大,采用的是数位 DP + KMP的方法。数位DP 问题往往都是这样的题型,给定一个闭区间([l, r]),让你求这个区间中满足某种条件的数的总数。数位DP实际上是DFS+记忆化搜索,关于数位DP的基础知识可以参考数位DP
    这道题的最大难点在于,我们要求计算有多少个字符串“不包含”某个子串,通过KMP算法是便于我们找出当前字符串与模式串的最大匹配位数,当出现下一位不匹配时,我们可以直接找出下一个需要匹配的字符位置,这里也就是next数组的作用了。

    class Solution:
        def findGoodStrings(self, n: int, s1: str, s2: str, evil: str) -> int:
            MOD = 1000000007
            if s1 > s2:
                return 0
            self.next_ = self.getNext(evil)
            self.dp = [[-1 for j in range(len(evil))] for i in range(n)]
            ans = self.dfs(s2,evil,0, 0, True) % MOD - self.dfs(s1,evil,0, 0, True) % MOD + MOD
            if evil not in s1:
                ans += 1
            return ans % MOD
    
        def getNext(self, p):
            p += '*'
            len_p = len(p)
            next = [-1 for i in range(len_p)]
            j,k = 0,-1
            while j<len_p-1:
                if p[j] == p[k] or k==-1:
                    j+=1
                    k+=1
                    next[j] = k
                else:
                    k = next[k]
            return next
    
        def dfs(self,s,evil,x,match,flag):
            n,m = len(s),len(evil)
            if match >= m:
                return 0
            if x >= n:
                return 1
            if not flag and  self.dp[x][match] != -1:
                return self.dp[x][match];
            lim = s[x] if flag else 'z'
            ret = 0
            for k in range(ord('a'),ord(lim)+1):
                cur = chr(k)
                nxt = match;
                while nxt > 0 and evil[nxt] != cur:
                      nxt = self.next_[nxt]
                if cur == evil[nxt]: nxt += 1
                ret += self.dfs(s,evil,x + 1, nxt, flag and (cur == lim))
    
            if not flag: self.dp[x][match] = ret
            return ret
    

    参考:
    leetcode

  • 相关阅读:
    设置root密码
    切分和组合图片(一)
    android 游戏开发libgdx(一)
    用SharePoint.OpenDocuments打开的文档如何控制它的ActiveWindow.View.ShowXMLMarkup(转)
    sp_helptext 命令
    CMMI 配置管理 简介(转)
    文本框中只能输入字符的正则表达式.
    基于CMM和CMMI的配置管理(转)
    正则表达式详述(转)
    选中多个CheckBox赋给文本框.
  • 原文地址:https://www.cnblogs.com/hellojamest/p/12619096.html
Copyright © 2011-2022 走看看