LeetCode 每日一题 2023/3/20-2023/3/26

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




3/20 1012. 至少有 1 位重复的数字

寻找[1…n]中没有重复数字的个数 只要将其去除即是答案
用十位二进制mask 表示0~9是否出现过
将n的各位数字放入nums中 从低位到高位
从n的高位开始依次探索
limit表示当前位是否有限制
若无限制及改为不是当前有数值的最高位则可以为0~9 否则不能超过该位原有数值
lead=True表示比该位高的位数都为0

def numDupDigitsAtMostN(n):
    """
    :type n: int
    :rtype: int
    """
    global mem
    mem = {}
    nums = []
    while n:
        nums.append(n%10)
        n//=10
    def dfs(loc,mask,lead,limit):
        global mem
        if (loc,mask,lead,limit) in mem:
            return mem[(loc,mask,lead,limit)]
        if loc<0:
            return int(lead)^1
        up = nums[loc] if limit else 9
        ans = 0
        for i in range(up+1):
            if mask>>i &1:
                continue
            if i==0 and lead:
                ans += dfs(loc-1,mask,lead,limit and i==up)
            else:
                ans += dfs(loc-1,mask|1<<i,False,limit and i==up)
        mem[(loc,mask,lead,limit)] = ans
        return ans
    return n-dfs(len(nums)-1,0,True,True)



3/21 2469. 温度转换

按规则转换

def convertTemperature(celsius):
    """
    :type celsius: float
    :rtype: List[float]
    """
    return [celsius+273.15,celsius*1.8+32.0]



3/22 1626. 无矛盾的最佳球队

将队员按年级从小到大排序
如果年纪相同 按分数从小到大排序 num
动态规划
dp[j]代表以j为最后一名球员时的最大分数
只要j>i说明j的年纪不小于i
且j的分数大于i
必定可以dp[j] = max(dp[j],dp[i]+num[j][1])

def bestTeamScore(scores, ages):
    """
    :type scores: List[int]
    :type ages: List[int]
    :rtype: int
    """
    n = len(scores)
    num = sorted(zip(ages,scores))
    dp = [0]*n
    ans = 0
    for j in range(n):
        for i in range(j):
            if num[j][1]>=num[i][1]:
                dp[j] = max(dp[i],dp[j])
        dp[j] += num[j][1]
        ans = max(ans,dp[j])
    return ans



3/23 1630. 等差子数组

遍历m种情况
对每种情况进行判断

def checkArithmeticSubarrays(nums, l, r):
    """
    :type nums: List[int]
    :type l: List[int]
    :type r: List[int]
    :rtype: List[bool]
    """
    m = len(l)
    ans = [False]*m
    for i in range(m):
        li = nums[l[i]:r[i]+1]
        minv,maxv = min(li),max(li)
        if minv==maxv:
            ans[i] = True
            continue
        if (maxv-minv)%(r[i]-l[i])>0:
            continue
        diff = (maxv-minv)//(r[i]-l[i])
        tag = True
        mem=set()
        for j in range(l[i],r[i]+1):
            if (nums[j]-minv)%diff>0:
                tag = False
                break
            tmp = nums[j]-minv
            if tmp in mem:
                tag = False
                break
            mem.add(tmp)
        if tag:
            ans[i] =tag
    return ans



3/24 1032. 字符流

words中长度最大为max 只保留最近max个字符
记录words中的字符长度到len中
l中记录最近max个字符 一次考虑len中长度的后缀是否在words中

class StreamChecker(object):

    def __init__(self, words):
        """
        :type words: List[str]
        """
        self.s = set(words)
        self.max = max([len(w) for w in words])
        self.len = list(set([len(w) for w in words]))
        self.l = ""


    def query(self, letter):
        """
        :type letter: str
        :rtype: bool
        """
        if len(self.l)==self.max:
            self.l = self.l[1:]
        self.l += letter
        n = len(self.l)
        for le in self.len:
            if self.l[n-le:] in self.s:
                return True
        return False



3/25 1574. 删除最短的子数组使剩余数组有序

双指针 删减区间[i,j]
j从后往前 一直到最先遇到递减的位置
i从前往后 如果arr[j]小于arr[i]则需要将j往后移
一直到i从前往后遇到了递减位置则退出

def findLengthOfShortestSubarray(arr):
    """
    :type arr: List[int]
    :rtype: int
    """
    n = len(arr)
    j = n-1
    while j>0 and arr[j-1]<=arr[j]:
        j -=1
    if j==0:
        return 0
    ans = j
    for i in range(n):
        while j<n and arr[j]<arr[i]:
            j +=1
        ans = min(ans,j-i-1)
        if i+1<n and arr[i]>arr[i+1]:
            break
    return ans



3/26 2395. 和相等的子数组

遍历所有长度为2的子数组
保存出现和的可能性 如果有重复返回true

def findSubarrays(nums):
    """
    :type nums: List[int]
    :rtype: bool
    """
    n = len(nums)
    s = set()
    for i in range(n-1):
        cur = nums[i]+nums[i+1]
        if cur in s:
            return True
        s.add(cur)
    return False
        



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值