LeetCode 每日一题 2023/1/2-2023/1/8

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


目录

      • 1/2 1801. 积压订单中的订单总数
      • 1/3 2042. 检查句子中的数字是否递增
      • 1/4 1802. 有界数组中指定下标处的最大值
      • 1/5 1803. 统计异或值在范围内的数对有多少
      • 1/6 2180. 统计各位数字之和为偶数的整数个数
      • 1/7 1658. 将 x 减到 0 的最小操作数
      • 1/8 2185. 统计包含给定前缀的字符串


1/2 1801. 积压订单中的订单总数

小顶堆存储卖的 大顶堆存储买的

def getNumberOfBacklogOrders(orders):
    """
    :type orders: List[List[int]]
    :rtype: int
    """
    MOD = 10**9+7
    ans = 0
    buy,sell = [],[]
    import heapq
    for p,n,t in orders:
        if t==0:
            while n>0 and sell:
                pr,num = sell[0]
                if p>=pr:
                    pr,num = heapq.heappop(sell)
                    if num>n:
                        heapq.heappush(sell, (pr,num-n))
                        ans = (ans-n)%MOD
                        n = 0
                    else:
                        ans = (ans-num)%MOD
                        n -=num
                    print(ans)
                else:
                    break
            if n>0:
                heapq.heappush(buy, (-p,n))
                ans = (ans+n)%MOD
        else:
            while n>0 and buy:
                pr,num = buy[0]
                if -pr>=p:
                    pr,num = heapq.heappop(buy)
                    if num>n:
                        heapq.heappush(buy, (pr,num-n))
                        ans = (ans-n)%MOD
                        n = 0
                    else:
                        ans = (ans-num)%MOD
                        n-=num
                else:
                    break
            if n>0:
                heapq.heappush(sell, (p,n))
                ans = (ans+n)%MOD
    return ans



1/3 2042. 检查句子中的数字是否递增

分割检查每个单词

def areNumbersAscending(s):
    """
    :type s: str
    :rtype: bool
    """
    l = s.split(" ")
    cur = 0
    for c in l:
        if c.isdigit():
            if cur<int(c):
                cur = int(c)
            else:
                return False
    return True



1/4 1802. 有界数组中指定下标处的最大值

每一位必定大于等于1
初始每一位为1
第二步 将index处+1
第三步 将[index-1,index+1]处+1
直到无法分配maxSum

def maxValue(n, index, maxSum):
    """
    :type n: int
    :type index: int
    :type maxSum: int
    :rtype: int
    """
    ans = 1
    maxSum -= n
    i = 0
    while maxSum>0:
        l = min(index+i,n-1)-max(0,index-i)+1
        if maxSum>=l:
            if l==n:
                ans += maxSum//l
            maxSum-=l
            ans+=1
            i+=1
        else:
            break
    return ans



1/5 1803. 统计异或值在范围内的数对有多少

异或x^y = t 等价于 x^t = y
所以在寻找nums中的x,y时 可以根据t=[low,high]和x 来确认y
cnt统计每个num个数 及cnt[x]*cnt[x^t] 因为cnt[y]*cnt[y^t]又会统计一次
所以答案只需要一半
先算出[0,high]-[0,low]为答案

def countPairs(nums, low, high):
    """
    :type nums: List[int]
    :type low: int
    :type high: int
    :rtype: int
    """
    import Counter
    ans = 0
    cnt = Counter(nums)
    high+=1
    while high:
        nxt = Counter()
        for x,c in cnt.items():
            if high&1:
                ans += c*cnt[x^(high-1)]
            if low&1:
                ans -= c*cnt[x^(low-1)]
            nxt[x>>1]+=c
        cnt = nxt
        low>>=1
        high>>=1
    return ans//2



1/6 2180. 统计各位数字之和为偶数的整数个数

设num = 10*i+j
对于i个10里 必定包含5个满足条件的数
只要考虑最后j个数即可

def countEven(num):
    """
    :type num: int
    :rtype: int
    """
    i = num//10
    j = num%10
    ans = i*5
    s = 0
    while i:
        s += i%10
        i //=10
    if s%2==0:
        ans += j//2
    else:
        ans += (j+1)//2-1
    return ans



1/7 1658. 将 x 减到 0 的最小操作数

suml,sumr用来记录前缀 后缀的和
l,r记录前缀[0,l] 后缀的位置[r,n]
初始空前缀l=-1,全后缀r=0
遍历每一个前缀l
如果suml+sumr>x 则减少后缀

def minOperations(nums, x):
    """
    :type nums: List[int]
    :type x: int
    :rtype: int
    """
    n = len(nums)
    s = sum(nums)
    if s<x:
        return -1
    suml,sumr = 0,s
    r = 0
    ans = n+1
    for l in range(-1,n-1):
        if l!=-1:
            suml+=nums[l]
        while r<n and suml+sumr>x:
            sumr-=nums[r]
            r+=1
        if suml+sumr==x:
            ans = min(ans,l+1+n-r)
    return -1 if ans>n else ans



1/8 2185. 统计包含给定前缀的字符串

依次统计

def prefixCount(words, pref):
    """
    :type words: List[str]
    :type pref: str
    :rtype: int
    """
    ans = 0
    n = len(pref)
    for word in words:
        if len(word)>=n and word[:n]==pref:
            ans +=1
    return ans




你可能感兴趣的:(Exercise,leetcode,算法)