LeetCode 每日一题 2022/5/9 -2022/5/15

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




5/9 942. 增减字符串匹配

如果s[i]=I 那么假设perm[i]=最小值 min(nums)
此时无论i+1取何值 必定满足perm[i]<perm[i+1]
同理如果s[i]=D perm[i] = max(nums)

def diStringMatch(s):
    """
    :type s: str
    :rtype: List[int]
    """
    n = len(s)
    l = [0]*(n+1)
    minv = 0
    maxv = n
    for loc,c in enumerate(s):
        if c=="I":
            l[loc] = minv
            minv+=1
        else:
            l[loc] = maxv
            maxv-=1
    l[n] = minv
    return l



5/10 1728. 猫和老鼠 II

没想出来
缓存lru_cache
参考https://leetcode.cn/problems/cat-and-mouse-ii/solution/python-ji-xiao-ji-da-bo-yi-by-himymben-ukbk/

def canMouseWin(grid, catJump, mouseJump):
    """
    :type grid: List[str]
    :type catJump: int
    :type mouseJump: int
    :rtype: bool
    """
    move = [(0,1),(0,-1),(-1,0),(1,0)]
    n,m = len(grid),len(grid[0])
    for i in range(n):
        for j in range(m):
            if grid[i][j]=="C":
                cat = (i,j)
            elif grid[i][j] =="F":
                food = (i,j)
            elif grid[i][j] == "M":
                mouse = (i,j)
                
    @lru_cache(None)
    def dfs(mloc,cloc,i):
        if mloc==cloc or cloc==food or i>128:
            return False
        if mloc == food:
            return True
        pos,jump = mloc,mouseJump
        cat_turn = False
        if i%2:
            pos,jump = cloc,catJump
            cat_turn = True
        for dx,dy in move:
            for step in range(jump+1):
                nx,ny = pos[0]+dx*step,pos[1]+dy*step
                if nx<0 or ny<0 or nx>=n or ny>=m or grid[nx][ny]=="#":
                    break
                if not cat_turn and dfs((nx,ny),cloc,i+1):
                    return True
                elif cat_turn and not dfs(mloc,(nx,ny),i+1):
                    return False
        return cat_turn
    return dfs(mouse,cat,0)



5/11 449. 序列化和反序列化二叉搜索树

后序遍历

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

class Codec:
    def serialize(self, root: TreeNode) -> str:
        """Encodes a tree to a single string.
        """
        ans = []
        def find(node):
            if node:
                find(node.left)
                find(node.right)
                ans.append(node.val)
        find(root)
        return " ".join(map(str,ans))
        

    def deserialize(self, data: str) -> TreeNode:
        """Decodes your encoded data to tree.
        """
        l = list(map(int,data.split()))
        def build(minv,maxv):
            if l==[] or l[-1]<minv or l[-1]>maxv:
                return None
            val = l.pop()
            node = TreeNode(val)
            node.right = build(val,maxv)
            node.left = build(minv,val)
            return node
        return build(-1,10001)



5/12 944. 删列造序

依次比较 每个字符串有n个字符
从第1位开始 比较每一个字符串该位置是否升序

def minDeletionSize(strs):
    """
    :type strs: List[str]
    :rtype: int
    """
    n = len(strs[0])
    ans = 0
    if len(strs)==0:
        return ans
    for i in range(n):
        cur = strs[0][i]
        for c in strs[1:]:
            if c[i]<cur:
                ans +=1
                break
            cur = c[i]
    return ans



5/13 面试题 01.05. 一次编辑

两个字符串长度差不能大于1
如果长度相同 记录不同字符的次数 不能大于1
如果长度不同 从头比较 遇到不同的 长字符串跳过 继续比较

def oneEditAway(first, second):
    """
    :type first: str
    :type second: str
    :rtype: bool
    """
    if first==second:
        return True
    n = len(first)
    m = len(second)
    if abs(n-m)>1:
        return False
    
    if n>m:
        first,second=second,first
        n,m=m,n
        
    if n<m:
        i,j=0,0
        check = True
        while j<m:
            if i==n:
                return True
            if first[i]!=second[j]:
                if check:
                    j+=1
                    check = False
                else:
                    return False
            else:
                i+=1
                j+=1
        return True
    else:
        diff=[]
        for i in range(n):
            if first[i]!=second[i]:
                if len(diff)==1:
                    return False
                diff.append(i)
        
        if len(diff)<2:
            return True
        
        
        return False



5/14 691. 贴纸拼词

target最多15位 用一个15位的二进制mask用来标识target的子序列
首先判断target是否包含sticker中没有的字母 如果有则返回-1
mem[mask]记录以判断过得子序列最优解
dfs判断mask的最优解
遍历每一个sticker left为mask去除sticker内字符后的子序列

def minStickers(stickers, target):
    """
    :type stickers: List[str]
    :type target: str
    :rtype: int
    """
    from collections import defaultdict
    n = len(target)
    
    has = 0
    for s in stickers:
        for c in s:
            has |= 1<<(ord(c)-ord("a"))
    for c in target:
        if has&(1<<(ord(c)-ord("a")))==0:
            return -1
    mem = {}
    mem[0] = 0
    def find(mask):
        if mask in mem:
            return mem[mask]
        ans = n+1
        for s in stickers:
            left = mask
            m = defaultdict(int)
            for c in s:
                m[c]+=1
            for i,c in enumerate(target):
                if mask>>i &1 and m[c]:
                    m[c]-=1
                    left ^= 1<<i
            if left<mask:
                ans = min(ans,find(left)+1)
        mem[mask] = ans
        return ans
    ans = find((1<<n)-1)
    return ans



5/15 812. 最大三角形面积

海伦公式 三角形三条边a,b,c
面积= 根号(p(p-a)(p-b)(p-c)) p=(a+b+c)/2
点的个数小于等于50 三重循环遍历
小数有误差判断一下 在同一条直线 tmp<0情况


def largestTriangleArea(points):
    """
    :type points: List[List[int]]
    :rtype: float
    """
    import math
    def findlen(a,b):
        return math.sqrt(math.pow(a[0]-b[0],2)+math.pow(a[1]-b[1],2))
    cur = 0
    n = len(points)
    for i in range(n):
        for j in range(i+1,n):
            for k in range(j+1,n):
                a = findlen(points[i],points[j])
                b = findlen(points[i],points[k])
                c = findlen(points[k],points[j])
                p = (a+b+c)*0.5
                tmp = p*(p-a)*(p-b)*(p-c)
                if tmp<0:
                    continue
                s = (p*(p-a)*(p-b)*(p-c))**0.5
                cur = max(cur,s)
    return cur


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值