LeetCode 每日一题 2021/11/29-2021/12/5

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




11/29 786. 第 K 个最小的素数分数

1.对于一个数arr[j]
他能够生成的小数arr[i]/arr[j] 对于i(0<=i<j) 结果必定是单调递增的
最小的必定是arr[0]/arr[j] 将所有0<j的结果放入最小堆中
每次取当前最小值arr[i]/arr[j] 下一个为arr[i+1]/arr[j] (i+1<j)
重复k次可以拿到第k小的值
2.分数结果必定在0-1之间
二分分数的结果v
寻找小于v的个数有多少个
如果少于k个 说明结果比v大
否则结果比v小

def kthSmallestPrimeFraction1(arr, k):
    """
    :type arr: List[int]
    :type k: int
    :rtype: List[int]
    """
    import heapq
    n = len(arr)
    if k==1:
        return [arr[0],arr[1]]
    l = []
    first = arr[0]
    for i in range(1,n):
        tmp = (first/arr[i],0,i)
        heapq.heappush(l,tmp)

    
    while k>1:
        k-=1
        _,a,b = heapq.heappop(l)
        print(arr[a],arr[b])
        a+=1
        if a==b:
            continue
        tmp = (arr[a]/arr[b],a,b)
        heapq.heappush(l,tmp)
    _,a,b = heapq.heappop(l)
    return [arr[a],arr[b]]

def kthSmallestPrimeFraction(arr, k):
    """
    :type arr: List[int]
    :type k: int
    :rtype: List[int]
    """
    left,right =0.0,1.0
    n = len(arr)
    while True:
        mid = (left+right)/2.0
        i,num = -1,0
        a,b = 0,1
        
        for j in range(1,n):
            while arr[i+1]/arr[j]<mid:
                i+=1
                if arr[i]*b>arr[j]*a:
                    a,b = arr[i],arr[j]
            num += i+1
        if num==k:
            return [a,b]
        elif num<k:
            left = mid
        else:
            right = mid   

11/30 400. 第 N 位数字

一位数 1-9 9个
两位数 10-99 90个
三位数 100-999 900个
由此可见 对于i位数 一共有9*(10^i)个
首先判断第n位是几位数 base从9开始 90,900 i表示位数
剩余n表示在i位数中第几位数字
n//i表示i位的数字个数
offset= n%i表示在这个i位数中的第几位 如果offset=0 说明时前一个数的最后一位

def findNthDigit(n):
    """
    :type n: int
    :rtype: int
    """    
    base=9
    i =1
    while n>base*i:
        n-=base*i
        base*=10
        i+=1
    
    num = n//i
    offset = n%i
    value = 10**(i-1)+num
    if offset==0:
        offset=i
        value-=1
    print(n,num,offset,value)
    return int(str(value)[offset-1]) 

12/1 1446. 连续字符

依次遍历每个字符
curs记录当前连续的字符
如果当前字符c与连续字符相同 则连续数num+1
如果不同则连续字符curs变为c 连续数num=1

def maxPower(s):
    """
    :type s: str
    :rtype: int
    """
    ans = 1
    curs = s[0]
    num = 1
    for c in s[1:]:
        if c==curs:
            num+=1
        else:
            ans = max(ans,num)
            num=1
            curs = c
    return ans 

12/2 506. 相对名次

name用来存储第一名到第n名的名次
对score排序 记录排序后原有位置i
将排序后的名次填入对应位置i中

def findRelativeRanks(score):
    """
    :type score: List[int]
    :rtype: List[str]
    """
    top3 = ["Gold Medal","Silver Medal","Bronze Medal"]
    name = []
    n = len(score)
    for i in range(n):
        if i<3:
            name.append(top3[i])
        else:
            name.append(str(i+1))
            
    l = [(score[i],i) for i in range(n)]
    l.sort(reverse=True)
    ans = [""]*n
    loc=0
    for _,i in l:
        ans[i] =name[loc] 
        loc+=1
    return ans

12/3 1005. K 次取反后最大化的数组和

思路:
为了使和最大 目标将负数取反变为正数
如果全部为正数 则将最小的正数变为负数
从小到大排序 从最小的负数开始取反变为正数 直至k个或者全为正数为止
如果全为正数 并且次数还没有到k次
反复将正数中的最小数x取反 k为偶数则x依旧为x k为奇数则变为-x

 def largestSumAfterKNegations(nums, k):
    """
    :type nums: List[int]
    :type k: int
    :rtype: int
    """
    nums.sort()
    n = len(nums)
    loc = 0
    while k>0 and loc<n:
        if nums[loc]>=0:
            break
        nums[loc] = -nums[loc]
        k-=1
        loc+=1
    
    minv = min(nums)
    s = sum(nums)
    if k%2==0:
        return s
    else:
        return s-2*minv  

12/4 383. 赎金信

记录杂志中有的所有字符个数
遍历赎金信字符 如果字符个数小于零 说明不成功

def canConstruct(ransomNote, magazine):
    """
    :type ransomNote: str
    :type magazine: str
    :rtype: bool
    """
    if len(magazine)<len(ransomNote):
        return False
    from collections import defaultdict
    m = defaultdict(int)
    for c in magazine:
        m[c]+=1
        
    for c in ransomNote:
        m[c]-=1
        if m[c]<0:
            return False
    return True

12/5 372. 超级次方

从高位到低位 十倍
假设当前位为c
ans为当前结果 = 上一位ans10 * ac

def superPow(a, b):
    """
    :type a: int
    :type b: List[int]
    :rtype: int
    """
    MOD = 1337
    ans = 1
    for c in b:
        ans = (pow(ans,10,MOD)*pow(a,c,MOD))%MOD
    return ans   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值