LeetCode 每日一题 2021/9/27-2021/10/3

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




9/27 639. 解码方法 II

动态规划
dp[i] 代表s前i个字符的解码数
使用1个字符:
s[i]为* 可以为1-9 dp[i] = 9dp[i-1]
s[i]为0 无法解码 dp[i] = 0
否则s[i]=[1,9] dp[i] = dp[i-1]
使用2个字符:
s[i],s[i-1]都为
可以为[11-19,21-26]十五种情况 dp[i] = 15dp[i-2]
只有s[i]为
s[i]=1 dp[i]=9dp[i-2] s[i]=2 dp[i]=6dp[i-2] 否则 dp[i]=0
只有s[i-1]为* s[i-1]=[1,6] dp[i]=2dp[i-2] s[i-1]=[7,9] dp[i]=dp[i-2]
若都不为
只有s[i-1]!=0且s[i-1]s[i]<=“26” dp[i]=dp[i-2] 否则dp[i]=0
只有dp[i],dp[i-1],dp[i-2]相关 可以只用三个遍历
dp0,dp1,dp2
dp0 = xdp1+ydp2

def numDecodings(s):
    """
    :type s: str
    :rtype: int
    """
    mod = 10**9+7
    def one(c):
        if c=="0":
            return 0
        elif c=="*":
            return 9
        else:
            return 1
    def two(c0,c1):
        if c0==c1=="*":
            return 15
        if c0=="*":
            if c1<="6":
                return 2
            else:
                return 1
        if c1=="*":
            if c0=="1":
                return 9
            elif c0=="2":
                return 6
            else:
                return 0 
        if c0>"0" and int(c0+c1)<=26:
            return 1
        else:
            return 0
    n = len(s)
    dp0,dp1,dp2 = 0,1,0
    for i in range(n):
        dp0 = dp1*one(s[i])
        if i>0:
            dp0 += dp2*two(s[i-1],s[i])
        dp0 %=mod
        dp2 = dp1
        dp1 = dp0
        print(s[i],dp0,dp1,dp2)
    return dp0

9/28 437. 路径总和 III

start用来寻找从root点作为起点的情况
同时考虑从左右子节点作为起点的情况
注意 当sum==val时不能停止 需要继续往下找 存在和为0的情况

class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None


def pathSum(root, targetSum):
    """
    :type root: TreeNode
    :type sum: int
    :rtype: int
    """
    def start(root,sum):
        ret = 0
        if not root:
            return ret
        if root.val == sum:
            ret+=1
        
        if root.left:
            ret += start(root.left,sum-root.val)
        if root.right:
            ret += start(root.right,sum-root.val)
            
        return ret
    
    if not root:
        return 0
    res = start(root,targetSum)
    res += pathSum(root.left,targetSum)
    res += pathSum(root.right,targetSum)
    
    return res

9/29 517. 超级洗衣机

计算总件数 如果无法均分 返回失败-1
得到每台洗衣机最终需要的件数ave
如果一台洗衣机件数小于ave 那么它左右都可以给他衣服
但如果一台洗衣机件数v大于ave 那么它至少需要v-ave次才能把衣服给出去
使用前缀和presum记录前i台目前有的总件数
对于第i台洗衣机 前i台最终需要的件数为iave
那么缺少或者多余的件数为 abs(presum-i
ave)
这些件数需要从左往右 或者从右往左经过i
取每个位置最大操作次数

def findMinMoves(machines):
    """
    :type machines: List[int]
    :rtype: int
    """
    total = sum(machines)
    n = len(machines)
    if total%n>0:
        return -1
    ave = total//n
    presum = 0
    ans = 0
    for i,v in enumerate(machines):
        diff = v-ave
        presum +=v
        ans = max(ans,max(diff,abs(presum-(i+1)*ave)))
    return ans

9/30 223. 矩形面积

分别计算两个矩形面积s1,s2 需要求重叠矩形面积over
1.将左下角点靠左边的设为a
分别考虑a左下点在b左下点的下面;上面两种情况
以上两种情况中 出去不想交的情况 在分别考虑四种情况
2.将a,b两个矩形的长投影到x轴 宽投影到y轴 分别有两条线段
两条线段相交的的即为相交矩阵的长或宽

def computeArea(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2):
    """
    :type ax1: int
    :type ay1: int
    :type ax2: int
    :type ay2: int
    :type bx1: int
    :type by1: int
    :type bx2: int
    :type by2: int
    :rtype: int
    """
    s1 = (ax2-ax1)*(ay2-ay1)
    s2 = (bx2-bx1)*(by2-by1)
    
    if ax1>bx1:
        ax1, ay1, ax2, ay2, bx1, by1, bx2, by2 = bx1, by1, bx2, by2,ax1, ay1, ax2, ay2
        
    over = 0
    
    if ay1>=by1:
        if ay1>=by2:
            over = 0
        elif ax2<=bx1:
            over = 0
        elif ax2<=bx2 and ay2<=by2:
            over = (ax2-bx1)*(ay2-ay1)
        elif ax2<=bx2 and ay2>by2:
            over = (ax2-bx1)*(by2-ay1)
        elif ax2>bx2 and ay2<=by2:
            over = (bx2-bx1)*(ay2-ay1)
        elif ax2>bx2 and ay2>by2:
            over = (bx2-bx1)*(by2-ay1)
    else:
        if ay2<=by1:
            over = 0
        elif ax2<=bx1:
            over = 0
        elif ax2<=bx2 and ay2<=by2:
            over = (ax2-bx1)*(ay2-by1)
        elif ax2<=bx2 and ay2>by2:
            over = (ax2-bx1)*(by2-by1)
        elif ax2>bx2 and ay2<=by2:
            over = (bx2-bx1)*(ay2-by1)
        elif ax2>bx2 and ay2>by2:
            over = (bx2-bx1)*(by2-by1)
    return s1+s2-over

def computeArea2(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2):
    """
    :type ax1: int
    :type ay1: int
    :type ax2: int
    :type ay2: int
    :type bx1: int
    :type by1: int
    :type bx2: int
    :type by2: int
    :rtype: int
    """
    s1 = (ax2-ax1)*(ay2-ay1)
    s2 = (bx2-bx1)*(by2-by1)
    
    overw = min(ax2,bx2)-max(ax1,bx1)
    overh = min(ay2,by2)-max(ay1,by1)
    overs = max(overw,0)*max(overh,0)
    return s1+s2-overs

10/1 1436. 旅行终点站

target存储所有出现的终点站
source存储所有出现的起点
从target中找到一个未出现在source中的点即为最终终点站

def destCity(paths):
    """
    :type paths: List[List[str]]
    :rtype: str
    """
    target = set()
    source = set()
    for s,t in paths:
        source.add(s)
        target.add(t)
    
    for loc in target:
        if loc not in source:
            return loc

10/2 405. 数字转换为十六进制数

s为16进制用到的字符
32位转化为16进制 最多8位 循环最多8次
num对16取余 -1%16=15
余数即为当前位结果
最后将结果倒序输出

def toHex(num):
    """
    :type num: int
    :rtype: str
    """
    s = "0123456789abcdef"
    ans = []
    for _ in range(8):
        ans.append(num%16)
        num = num//16
        if not num:
            break
    return "".join(s[i] for i in ans[::-1])

10/3 166. 分数到小数

x/y
如果可以整除 则直接返回结果
s用来记录结果
如果x,y正负不同 则结果为负数 添加"-"
整数部分 x//y 并且添加"."
余数部分 yu=x%y
index用来记录出现过的余数 如果该余数已经出现过 说明后续结果会重复
记录当前yu数位置
每次yu乘以10 用来除以y 为当前位结果
得到新余数 yu=yu%y
退出循环 如果yu不为0 说明存在循环
找到位置ind=index[yu]
添加"(" 并在结尾添加")"
将结果组合成字符串输出

def fractionToDecimal(numerator, denominator):
    """
    :type numerator: int
    :type denominator: int
    :rtype: str
    """
    if numerator%denominator==0:
        return str(numerator//denominator)
    s = []
    if (numerator>0)!=(denominator>0):
        s.append("-")
        
    x = abs(numerator)
    y = abs(denominator)
    z = x//y
    s.append(str(z))
    s.append(".")
    
    yu = x%y
    index = {}
    while yu and yu not in index:
        index[yu] = len(s)
        yu *=10
        s.append(str(yu//y))
        yu = yu%y
    if yu:
        ind = index[yu]
        s.insert(ind,"(")
        s.append(")")
    return "".join(s)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值