LeetCode 每日一题 2021/8/9-2021/8/15

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




8/9 313. Super Ugly Number 超级丑数

除1外 大的丑数必定是小的丑数乘以primes中的一个质数
l记录当前丑数
p[i]记录质数i在序列中乘的一个小丑数位置
比较所有ip[i] 找到最小的tmp及为下一个丑数
将所有满足tmp==i
p[i]的质数i的位置后移一位 p[i]++

def nthSuperUglyNumber(n, primes):
    """
    :type n: int
    :type primes: List[int]
    :rtype: int
    """
    p = {}
    for i in primes:
        p[i]=0
    l = [1]
    loc = 0
    while loc<n-1:
        loc +=1
        tmp = min([i*l[p[i]] for i in primes])
        l.append(tmp)
        for i in primes:
            if i*l[p[i]]==tmp:
                p[i]+=1
    return l[n-1]


8/10 413. Arithmetic Slices 等差数列划分

计算差分数组
获取连续相等的差长度 计算这个长度能够组成的


def numberOfArithmeticSlices(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    if len(nums)<3:
        return 0
    diff = []
    for i in range(1,len(nums)):
        diff.append(nums[i]-nums[i-1])
    
    l,r = 0,0
    ans = 0
    while r<len(diff):
        if diff[l]!=diff[r]:
            ans +=(r-l-1)*(r-l)//2
            l = r
        r+=1
    ans +=(r-l-1)*(r-l)//2
    return ans

8/11 446. Arithmetic Slices II - Subsequence 等差数列划分 II - 子序列

dp
dp[i][d] 定义为以nums[i]为末尾 d位公差 至少存在两个元素的数列个数
遍历每个元素对 nums[j],nums[i] j<i d=nums[i]-nums[j]
此时 dp[j][d]的所有数列加上nums[i] 必定组成了三个元素及以上的等差数列 ans+=nums[j][d]
dp[i][d] += dp[j][d]+1

def numberOfArithmeticSlices(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    n = len(nums)
    if n<3:
        return 0
    from collections import defaultdict
    dp = [defaultdict(int) for _ in range(n)]
    ans = 0
    for i in range(n):
        for j in range(i):
            d = nums[i]-nums[j]
            ans += dp[j][d]
            dp[i][d] += dp[j][d]+1
    return ans

8/12 516. Longest Palindromic Subsequence 最长回文子序列

dp
dp[i][j] 表示[i,j]之间的最长回文子序列
初始化dp[i][i]==1
如果s[i]==s[j] 则dp[i][j]=dp[i+1][j-1]+2
否则 找到max(dp[i+1][j],dp[i][j-1])

def longestPalindromeSubseq(s):
    """
    :type s: str
    :rtype: int
    """
    n = len(s)
    dp = [[0]*n for _ in range(n)]
    for i in range(n):
        dp[i][i]=1
        
    for i in range(n-1,-1,-1):
        for j in range(i+1,n):
            if s[i]==s[j]:
                dp[i][j]=dp[i+1][j-1]+2
            else:
                dp[i][j] = max(dp[i+1][j],dp[i][j-1])
                
    return dp[0][n-1]

8/13 233. Number of Digit One 数字 1 的个数

考虑每一位1出现的次数
i代表当前位数因子 10**位数(从0开始)
对于当前为cur=num%10 其左边高位为num//10 右边低位为n%i
分情况考虑
如果cur0:
在当前为出现1的次数只与高位相关 [0,num//10) 个数为num//10 * i
如果cur
1:
与高位低位都有关 及cur=0时的结果加上cur=1时低位的个数 num//10i+(n%i+1)
如果cur>1:
只与高位有关 cur=0时num//10
i个以及cur=1时i个 num//10*i+i

def countDigitOne(n):
    """
    :type n: int
    :rtype: int
    """
    i = 1
    s = 0
    num = n
    while num>0:
        if num%10==0:
            s+=(num//10)*i
        if num%10==1:
            s+=(num//10)*i+(n%i)+1 ##119 11%10==1 10~19需要补充
        if num%10>1:
            s+=(num//10)*i+i
        num=num//10
        i*=10
    return s

8/14 1583. Count Unhappy Friends 统计不开心的朋友

order[x][y] 用来记录x与y的亲近程度 index 越靠前越亲近
couple[x]=y 记录当前x配对的y
得到当前配对的x,y 的亲近程度index
遍历[0,index) 的u
如果当前u的亲近程度order[u][v]>order[u][x] 则x不开心

def unhappyFriends(n, preferences, pairs):
    """
    :type n: int
    :type preferences: List[List[int]]
    :type pairs: List[List[int]]
    :rtype: int
    """
    order = [[0]*n for _ in range(n)]
    for i in range(n):
        for j in range(n-1):
            order[i][preferences[i][j]] = j
            
    couple = [0]*n
    for x,y in pairs:
        couple[x]=y
        couple[y]=x
        
    ans = 0
    for x in range(n):
        y = couple[x]
        index = order[x][y]
        for i in range(index):
            u = preferences[x][i]
            v = couple[u]
            if order[u][x]<order[u][v]:
                ans +=1
                break
    return ans

8/15 576. Out of Boundary Paths 出界的路径数

move 为移动的四个方向
mem 记录在x,y上移动steps步数 出界的可能性 放置重复计算
对于位置x,y遍历四个方向
如果界内 则继续考虑界内的情况
如果出界 那么ans+1

def findPaths(m, n, maxMove, startRow, startColumn):
    """
    :type m: int
    :type n: int
    :type maxMove: int
    :type startRow: int
    :type startColumn: int
    :rtype: int
    """
    MOD = 10**9+7
    move = [(1,0),(0,1),(-1,0),(0,-1)]
    mem = {}
    def find(x,y,steps):
        if (x,y,steps) in mem:
            return mem[(x,y,steps)]
        if steps==0:
            return 0
        
        ans = 0
        for i,j in move:
            xx,yy = x+i,y+j
            if 0<=xx<m and 0<=yy<n:
                ans += find(xx,yy,steps-1)
            else:
                ans +=1
        ans = ans%MOD
        mem[(x,y,steps)] = ans
        return ans
    return find(startRow, startColumn,maxMove)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值