LeetCode 每日一题 2022/12/12-2022/12/18

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




12/12 1781. 所有子字符串美丽值之和

遍历每一个子串 记录字串中每种字符的出现次数

def beautySum(s):
    """
    :type s: str
    :rtype: int
    """
    from collections import defaultdict
    n = len(s)
    ans = 0
    for i in range(n-1):
        m = defaultdict(int)
        m[s[i]]=1
        for j in range(i+1,n):
            m[s[j]]+=1
            ans += max(m.values())-min(m.values())
    return ans
            



12/13 1832. 判断句子是否为全字母句

长度小于26必定不行 遍历 存入map 最后判断map长度

def checkIfPangram(sentence):
    """
    :type sentence: str
    :rtype: bool
    """
    n = len(sentence)
    if n<26:
        return False
    m = {}
    for c in sentence:
        m[c]=1
    return True if len(m)==26 else False




12/14 1697. 检查边长度限制的路径是否存在

并查集
对于某个查询p,q,limit
遍历所有边将小于limit的都加入到并查集中
最后如果p,q在同个集合说明可以走到
将查询limit从小到大排序可以重复使用并查集

def distanceLimitedPathsExist(n, edgeList, queries):
    """
    :type n: int
    :type edgeList: List[List[int]]
    :type queries: List[List[int]]
    :rtype: List[bool]
    """
    edgeList.sort(key=lambda x:x[2])
    un = list(range(n))
    def find(x):
        if un[x]!=x:
            un[x] = find(un[x])
        return un[x]
    def merge(a,b):
        un[find(a)]=find(b)
    ans = [False]*len(queries)
    ind = 0
    for i,(p,q,limit) in sorted(enumerate(queries),key = lambda x:x[1][2]):
        while ind < len(edgeList) and edgeList[ind][2]<limit:
            merge(edgeList[ind][1],edgeList[ind][0])
            ind+=1
        ans[i] = find(p)==find(q)
    return ans



12/15 1945. 字符串转化后的各位数字之和

第一次必定是字母转数字
后续继续k次

def getLucky(s, k):
    """
    :type s: str
    :type k: int
    :rtype: int
    """
    st = ""
    for c in s:
        v = ord(c)-ord("a")+1
        st += str(v)
    ans = int(st)
    for _ in range(k):
        tmp = 0
        while ans >0:
            tmp += ans%10
            ans //=10
        ans = tmp
        if ans<10:
            break
    return ans



12/16 1785. 构成特定和需要添加的最少元素

求和 与goal之间差值target 取绝对值后 需要多少个limit

def minElements(nums, limit, goal):
    """
    :type nums: List[int]
    :type limit: int
    :type goal: int
    :rtype: int
    """
    s = sum(nums)
    target = abs(goal-s)
    ans = target//limit
    if target%limit>0:
        ans +=1
    return ans



12/17 1764. 通过连接另一个数组的子数组得到一个数组

从头遍历groups内整数 和nums内整数是否能一一对应
nums内需要连续的子数组对应

def canChoose(groups, nums):
    """
    :type groups: List[List[int]]
    :type nums: List[int]
    :rtype: bool
    """
    n = len(nums)
    loc = 0
    for i,g in enumerate(groups):
        m = len(g)
        tag = False
        while loc<n and loc+m<=n:
            if nums[loc]==g[0]:
                if nums[loc:loc+m]==g:
                    loc = loc+m
                    tag = True
                    if i==len(groups)-1:
                        return True
                    break
                else:
                    loc+=1
            else:
                loc+=1
        if not tag:
            return False
    return False



12/18 1703. 得到连续 K 个 1 的最少相邻交换次数

将k个1挪到一起 为了交换次数最少
这k个1在之前必定也是连续的
假设第i个1为qi q0移动到x q1移动到x+1 q2移动到x+2
=>q0->x q1-1->x q2-2->x
设pi=qi-i 计算pi到x的距离和最小值 x为pi中位数为最右p(k/2)
g[i]为第i个1与前一个1之间0的数目
设s为p的前缀和 距离和为s0+sk-2s(k/2)-p(k/2)(k%2)
枚举第i个1 是结果中最左边的1

def minMoves(nums, k):
    """
    :type nums: List[int]
    :type k: int
    :rtype: int
    """
    g = []
    pre = [0]
    for i,num in enumerate(nums):
        if num==1:
            g.append(i-len(g))
            pre.append(pre[-1]+g[-1])
    n = len(g)
    if n==len(nums):
        return 0
    ans = float('inf')
    for i in range(n-k+1):
        sl = pre[i]
        sm = pre[i+k//2]
        sr = pre[i+k]
        ans = min(ans,sl+sr-2*sm - g[i+k//2]*(k%2))
    return ans
            



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值