LeetCode 每日一题 2025/6/23-2025/6/29

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




6/23 2081. k 镜像数字的和

镜像只考虑一半 翻转拼接必定镜像

def kMirror(k, n):
    """
    :type k: int
    :type n: int
    :rtype: int
    """
    def check(x):
        d=[]
        while x:
            d.append(x%k)
            x//=k
        return d==d[::-1]
    
    l,cnt,ans=1,0,0
    while cnt<n:
        r=l*10
        for op in [0,1]:
            for i in range(l,r):
                if cnt==n:
                    break
                cb=i
                x=(i//10 if op==0 else i)
                while x:
                    cb = cb*10+x%10
                    x//=10
                if check(cb):
                    cnt+=1
                    ans+=cb
        l=r
    return ans



6/24 2200. 找出数组中的所有 K 近邻下标

对于坐标i 判断区间max(i-k,0),min(i+k,n-1)中是否存在key
记录在[0,k-1]中key出现的最后位置last

def findKDistantIndices(nums, key, k):
    """
    :type nums: List[int]
    :type key: int
    :type k: int
    :rtype: List[int]
    """
    last=float("-inf")
    for i in range(k-1,-1,-1):
        if nums[i]==key:
            last = i
            break
    ans=[]
    n=len(nums)
    for i in range(n):
        if i+k<n and nums[i+k]==key:
            last = i+k
        if last>=i-k:
            ans.append(i)
    return ans



6/25 2040. 两个有序数组的第 K 小乘积

二分 对于当前值mid 判断小于mid的乘积个数

def kthSmallestProduct(nums1, nums2, k):
    """
    :type nums1: List[int]
    :type nums2: List[int]
    :type k: int
    :rtype: int
    """
    import bisect
    def find(x,v):
        if x>0:
            return bisect.bisect_right(nums2, v//x)
        elif x<0:
            return len(nums2)-bisect.bisect_left(nums2, -(-v//x))
        else:
            return len(nums2) if v>=0 else 0
        
    n=len(nums1)
    l,r=-10**10,10**10
    while l<=r:
        mid = (l+r)//2
        cnt = 0
        for i in range(n):
            cnt += find(nums1[i],mid)
        if cnt<k:
            l=mid+1
        else:
            r=mid-1
    return l



6/26 2311. 小于等于 K 的最长二进制子序列

0越多越好 选择全部0 添加后面的1

def longestSubsequence(s, k):
    """
    :type s: str
    :type k: int
    :rtype: int
    """
    ss=0 
    cnt = 0
    l = k.bit_length()
    for i,c in enumerate(s[::-1]):
        if c=='1':
            if i<l and ss+(1<<i)<=k:
                ss+=1<<i
                cnt+=1
        else:
            cnt+=1
    return cnt



6/27 2014. 重复 K 次的最长子序列

找到符合出现次数的字母
枚举全排列 检查是否为s的子序列
题解:https://leetcode.cn/problems/longest-subsequence-repeated-k-times/?envType=daily-question&envId=2025-06-27

def longestSubsequenceRepeatedK(s, k):
    """
    :type s: str
    :type k: int
    :rtype: str
    """
    from collections import Counter
    from itertools import permutations
    def check(seq,s):
        it = iter(s)
        return all(c in it for c in seq)
    
    
    cnt = Counter(s)
    a = [c for c,f in cnt.items() for _ in range(f//k)]
    a.sort(reverse=True)
    for i in range(len(a),0,-1):
        for p in permutations(a,i):
            seq=''.join(p)
            if check(seq*k,s):
                return seq
    return ''



6/28 2099. 找到和最大的长度为 K 的子序列

记录位置和数值 将数值从大到小排序取k个
按照位置从小到大输出

def maxSubsequence(nums, k):
    """
    :type nums: List[int]
    :type k: int
    :rtype: List[int]
    """
    n=len(nums)
    v=[[i,nums[i]] for i in range(n)]
    v.sort(key=lambda x:-x[1])
    ans = [val for _,val in sorted(v[:k])]
    return ans



6/29 1498. 满足条件的子序列数目

数值位置不影响结果 将数组从小到大排序
最小与最大相加如果大于target
说明最大值太大 去除最大值考虑下一个
最小与最大相加如果小于等于target
说明当前最小值与任何后续数值组合都满足
可以由2^(n-1)种可能

def numSubseq(nums, target):
    """
    :type nums: List[int]
    :type target: int
    :rtype: int
    """
    MOD=10**9+7
    MX=10**5
    p = [1]*MX
    for i in range(1,MX):
        p[i]=p[i-1]*2%MOD
    nums.sort()
    ans=0
    l,r=0,len(nums)-1
    while l<=r:
        if nums[l]+nums[r]<=target:
            ans=(ans+p[r-l])%MOD
            l+=1
        else:
            r-=1
    return ans%MOD



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值