LeetCode 每日一题 2024/12/16-2024/12/22

发布于:2025-02-11 ⋅ 阅读:(68) ⋅ 点赞:(0)

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




12/16 1847. 最近的房间

经房间按大小排序
先考虑minSize大的查询
将比minSize大的房间号放入ids序列中考虑
根据当前查询preferred_id 在ids中查找离他最近的两个id 比较差值大小

def closestRoom(rooms, queries):
    """
    :type rooms: List[List[int]]
    :type queries: List[List[int]]
    :rtype: List[int]
    """
    from sortedcontainers import SortedList
    n=len(rooms)
    rooms.sort(key=lambda x:x[1])
    m=len(queries)
    ans=[-1]*m
    ids=SortedList()
    j=n-1
    for i in sorted(range(m),key=lambda i:-queries[i][1]):
        pid,msize=queries[i]
        while j>=0 and rooms[j][1]>=msize:
            ids.add(rooms[j][0])
            j-=1
        diff=float("inf")
        k = ids.bisect_left(pid)
        if k:
            diff = pid-ids[k-1]
            ans[i]=ids[k-1]
        if k<len(ids) and ids[k]-pid<diff:
            ans[i]=ids[k]
    return ans
            



12/17 3291. 形成目标字符串需要的最少字符串数 I

对于每个word 与target求出在结束在target[i]的前缀能够匹配的最长前缀back[i]
动态规划 dp[i]表示前i个字母需要最少字符串数

def minValidStrings(words, target):
    """
    :type words: List[str]
    :type target: str
    :rtype: int
    """
    def prefix(word,target):
        s=word+"#"+target
        n=len(s)
        pi=[0]*n
        for i in range(1,n):
            j=pi[i-1]
            while j>0 and s[i]!=s[j]:
                j=pi[j-1]
            if s[i]==s[j]:
                j+=1
            pi[i]=j
        return pi
    n=len(target)
    back = [0]*n
    for w in words:
        pi = prefix(w, target)
        m=len(w)
        for i in range(n):
            back[i]=max(back[i],pi[m+1+i])
    dp=[0]+[10**9]*n
    for i in range(n):
        dp[i+1]=dp[i+1-back[i]]+1
        if dp[i+1]>n:
            return -1
    return dp[n]



12/18 3292. 形成目标字符串需要的最少字符串数 II

对于每个word 与target求出在结束在target[i]的前缀能够匹配的最长前缀back[i]
动态规划 dp[i]表示前i个字母需要最少字符串数

def minValidStrings(words, target):
    """
    :type words: List[str]
    :type target: str
    :rtype: int
    """
    def prefix(word,target):
        s=word+"#"+target
        n=len(s)
        pi=[0]*n
        for i in range(1,n):
            j=pi[i-1]
            while j>0 and s[i]!=s[j]:
                j=pi[j-1]
            if s[i]==s[j]:
                j+=1
            pi[i]=j
        return pi
    n=len(target)
    back = [0]*n
    for w in words:
        pi = prefix(w, target)
        m=len(w)
        for i in range(n):
            back[i]=max(back[i],pi[m+1+i])
    dp=[0]+[10**9]*n
    for i in range(n):
        dp[i+1]=dp[i+1-back[i]]+1
        if dp[i+1]>n:
            return -1
    return dp[n]



12/19 3285. 找到稳定山的下标

从头依次遍历 找到所有大于threshold的山峰 右侧的就是稳定的

def stableMountains(height, threshold):
    """
    :type height: List[int]
    :type threshold: int
    :rtype: List[int]
    """
    ans=[]
    for i in range(len(height)-1):
        if height[i]>threshold:
            ans.append(i+1)
    return ans



12/20 3138. 同位字符串连接的最小长度

如果是k个字符串拼接而成 那么所有字符出现次数必定是k的倍数
从小到大枚举len(s)=n的因数 检查每一个子字符串字符出现次数是否相同





12/21 2545. 根据第 K 场考试的分数排序

提取第K列的数值排序

def sortTheStudents(score, k):
    """
    :type score: List[List[int]]
    :type k: int
    :rtype: List[List[int]]
    """
    ans=[]
    l=[(score[i][k],i) for i in range(len(score))]
    l.sort(reverse=True)
    for _,i in l:
        ans.append(score[i])
    return ans



12/22 1387. 将整数按权重排序

记忆化搜索mem[x]记录x的权重

def getKth(lo, hi, k):
    """
    :type lo: int
    :type hi: int
    :type k: int
    :rtype: int
    """
    mem={}
    mem[1]=0
    def find(x):
        if x in mem:
            return mem[x]
        mem[x] = (find(x//2) if x%2==0 else find(3*x+1))+1
        return mem[x]
    
    l=list(range(lo,hi+1))
    l.sort(key=lambda x:(find(x),x))
    return l[k-1]