LeetCode 每日一题 2022/1/17-2022/1/23

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步




1/17 1220. 统计元音字母序列的数目

从一位开始考虑
a结尾 前面可以为 e,i,u
e结尾 前面可以为 a,i
i结尾 前面可以为 e,o
o结尾 前面可以为 i
u结尾 前面可以为 i,o

def countVowelPermutation(n):
    """
    :type n: int
    :rtype: int
    """
    MOD = 10**9+7
    l = [1,1,1,1,1]
    if n==1:
        return sum(l)
    for _ in range(n-1):
        tmp = [0]*5
        tmp[0] = (l[1]+l[2]+l[4])%MOD
        tmp[1] = (l[0]+l[2])%MOD
        tmp[2] = (l[1]+l[3])%MOD
        tmp[3] = (l[2])%MOD
        tmp[4] = (l[2]+l[3])%MOD
        l = tmp[:]
    return sum(l)%MOD

1/18 539. 最小时间差

分钟共有2460种可能
根据抽屉原理 如果timePoints>24
60 那么必定存在一对时间相同 答案为0
将时间转换为分钟 从小到大排序 比较相邻两数的时间差

def findMinDifference(timePoints):
    """
    :type timePoints: List[str]
    :rtype: int
    """
    day = 24*60
    if len(timePoints)>day:
        return 0
    def transform(s):
        l = s.split(":")
        ans = int(l[0])*60+int(l[1])
        return ans
    
    mem = set()
    l = []
    for s in timePoints:
        num = transform(s)
        if num in mem:
            return 0
        l.append(num)
        
    l.sort()
    ans = min(abs(l[-1]-l[0]),day-abs(l[-1]-l[0]))
    for i in range(len(l)-1):
        cur = min(l[i+1]-l[i],day-(l[i+1]-l[i]))
        ans = min(ans,cur)
    return ans

1/19 219. 存在重复元素 II

滑动窗口 保持k+1长度 记录长度内出现的数字个数
如果数字个数大于1 则成立

def containsNearbyDuplicate( nums, k):
    """
    :type nums: List[int]
    :type k: int
    :rtype: bool
    """
    from collections import defaultdict
    win = defaultdict(int)
    for i in range(min(len(nums),k+1)):
        win[nums[i]]+=1
        if win[nums[i]]>1:
            return True
    for i in range(k+1,len(nums)):
        win[nums[i-k-1]]-=1
        win[nums[i]]+=1
        if win[nums[i]]>1:
            return True
    return False

1/20 2029. 石子游戏 IX

石子总和被3整除为输 目标是尽可能不让和被3整除
将石子分为3类 余数为0,1,2
取余数为0的石子数 对总和没有影响 平稳换手
如果0的个数为偶数 不影响
为基数相当于调换先后手
为了使和不为3的倍数
如果A先取1 AB依次取112121212…
这种情况下 需要有1 但是2的个数需要大于1的个数
如果A先取2 AB依次取221212121…
这种情况下 需要有2 但是1的个数需要大于2的个数
综上
如果先手 1,2都至少有一个就可以赢
如果后手 需要1比2多超过两个 或者2比1多超过两个

def stoneGameIX(stones):
    """
    :type stones: List[int]
    :rtype: bool
    """
    s0,s1,s2 = 0,0,0
    for s in stones:
        if s%3==0:
            s0+=1
        elif s%3==1:
            s1+=1
        else:
            s2+=1
    if s0%2==0:
        return s1>0 and s2>0
    return s1-s2>2 or s2-s1>2

1/21 1345. 跳跃游戏 IV

BFS
valueToloc记录每个值的位置所在
对于arr[loc]=v
他可以到达 loc+1,loc-1或者valueToloc[v]中的所有位置
第一次搜索到必定是最少次数 visited记录被搜索到的位置
同个值的位置搜索过后之后不需要搜索这个地方 删除valueToloc[v]

def minJumps(arr):
    """
    :type arr: List[int]
    :rtype: int
    """
    from collections import defaultdict,deque
    valueToloc = defaultdict(list)
    for loc,v in enumerate(arr):
        valueToloc[v].append(loc)
        
    n = len(arr)
    l = deque()
    l.append((0,0))
    visited=  set()
    visited.add(0)    
    while l:
        loc,step = l[0]
        if loc==n-1:
            return step
        value = arr[loc]
        l.popleft()
        for tmp in valueToloc[value][::-1]:
            if tmp not in visited:
                visited.add(tmp)
                l.append((tmp,step+1))
        valueToloc[value]=[]
        
        if loc+1<n and loc+1 not in visited:
            visited.add(loc+1)
            l.append((loc+1,step+1))
        if loc-1>0 and loc-1 not in visited:
            visited.add(loc-1)
            l.append((loc-1,step+1))

1/22 1332. 删除回文子序列

如果s与s的倒序相同 一次即可以删除
因为只有a,b两种字母 所以第一次删除所有a 第二次删除所有b
最多两次就可以删完

def removePalindromeSub(s):
    """
    :type s: str
    :rtype: int
    """
    if s==s[::-1]:
        return 1
    return 2

1/23 2034. 股票价格波动

一个小顶堆记录最小值
一个大顶堆记录最大值
同时记录最值对应时间戳
一个哈希表记录时间戳的对应值
curr记录最新时间
如果从顶堆中取出最值 比较最值的时间戳在哈希表中的值是否一致
如果不一致说明这个值已经失效 舍弃
“”"

import heapq
class StockPrice(object):

    def __init__(self):
        self.min = []
        self.max = []
        heapq.heapify(self.min)
        heapq.heapify(self.max)
        self.curr = 0
        self.m = {}


    def update(self, timestamp, price):
        """
        :type timestamp: int
        :type price: int
        :rtype: None
        """
        self.curr = max(self.curr,timestamp)
        if timestamp not in self.m:
            self.m[timestamp] = price
            heapq.heappush(self.min,(price,timestamp))
            heapq.heappush(self.max,(-price,timestamp))
        elif price!=self.m[timestamp]:
            self.m[timestamp] = price
            heapq.heappush(self.min,(price,timestamp))
            heapq.heappush(self.max,(-price,timestamp))


    def current(self):
        """
        :rtype: int
        """
        return self.m[self.curr]


    def maximum(self):
        """
        :rtype: int
        """
        while True:
            maxp,tp = self.max[0]
            if self.m[tp]!=-maxp:
                print(tp,self.m[tp],maxp)
                heapq.heappop(self.max)
            else:
                return -maxp


    def minimum(self):
        """
        :rtype: int
        """
        while True:
            minp,tp = self.min[0]
            if self.m[tp]!=minp:
                heapq.heappop(self.min)
            else:
                return minp

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值