LeetCode 每日一题 2022/5/30-2022/6/5

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




5/30 1022. 从根到叶的二进制数之和

dfs 根节点能得到的值为左右子节点能得到值的和
如果为叶子节点则返回其值 若为空则返回0

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

def sumRootToLeaf(root):
    """
    :type root: TreeNode
    :rtype: int
    """
    def dfs(node,cur):
        if not node:
            return 0
        cur = (cur<<1) + node.val
        if (not node.left) and (not node.right):
            return cur
        return dfs(node.left,cur)+dfs(node.right,cur)
    
    return dfs(root,0)




5/31 剑指 Offer II 114. 外星文字典

拓扑排序
out[c]记录比字母c排序靠后的字母有哪些
inNum[c]记录字母c入度 即当前比字母c排序靠前未被处理的字母个数
依次遍历所有相邻的单词
将所有出现过的字母入度初始化为0
如果后一个单词为前一个单词的前缀 则不存在合法顺序
两个单词w1,w2出现首个位置字母不同时 u,v 可以得到u比v字典序小
则将v加入到out[u]中
并且v的入度+1 inNum[v]+=1
处理完后 可将入度为0的字母加入到序列l中
遍历序列l中的字母c 将字母c出的字母v 入度-1 如果入度变为0
则可以加入到l中
最后判断出现过的字母是否都在l中
如果缺失则说明有环 不存在合法顺序


def alienOrder(words):
    """
    :type words: List[str]
    :rtype: str
    """
    from collections import defaultdict
    out = defaultdict(list)
    inNum = {c:0 for c in words[0]}
    for i in range(1,len(words)):
        w1,w2 = words[i-1],words[i]
        if len(w1)>len(w2) and w1[:len(w2)]==w2:
            return ""
        for c in w2:
            inNum[c] = inNum.get(c,0)
        for u,v in zip(w1,w2):
            if u!=v:
                out[u].append(v)
                inNum[v] +=1
                break
    l = []
    for c in inNum:
        if inNum[c]==0:
            l.append(c)
    for c in l:
        for v in out[c]:
            inNum[v]-=1
            if inNum[v]==0:
                l.append(v)
    if len(l)==len(inNum):
        return "".join(l)
    return ""


6/1 473. 火柴拼正方形

先求总和 如果不是4的倍数则返回失败
将火柴从大到小排序 回溯
求出正方形每条边长l
将火柴依次放入每条边中 dfs 如果成功凑成边长l 返回成功
否则 取出火柴放入下一条边

def makesquare(matchsticks):
    """
    :type matchsticks: List[int]
    :rtype: bool
    """
    matchsticks.sort(reverse=True)
    total = sum(matchsticks)
    if total%4>0:
        return False
    l = total // 4
    li = [l]*4
    if matchsticks[0]>l:
        return False
    def dfs(loc):
        if loc==len(matchsticks):
            return True
        for i in range(4):
            li[i]-=matchsticks[loc]
            if li[i]>=0 and dfs(loc+1):
                return True
            li[i]+=matchsticks[loc]
        return False
    return dfs(0)



6/2 450. 删除二叉搜索树中的节点

寻找到key值的node 记录父节点par
在左子树中找到最大值或者 在右子树中找到最小值替换node的值
如果node是叶子节点 则父节点连接node的子树为空
特殊处理不包含节点 以及仅有一个key值节点

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

def deleteNode(root, key):
    """
    :type root: TreeNode
    :type key: int
    :rtype: TreeNode
    """
    node = root
    par = root
    if not root:
        return None
    if root.val == key and (not root.left) and (not root.right):
        return None
    while node.val!=key:
        par = node
        if node.left and key<node.val:
            node = node.left
            continue
        if node.right and key>node.val:
            node = node.right
            continue
        return root
    if node.left:
        pre = node
        tmp = node.left
        while tmp.right:
            pre = tmp
            tmp = tmp.right
        node.val = tmp.val
        if node.left.right:
            pre.right = tmp.left
        else:
            pre.left = tmp.left
    elif node.right:
        pre = node
        tmp = node.right
        while tmp.left:
            pre = tmp
            tmp = tmp.left
        node.val = tmp.val
        if node.right.left:
            pre.left = tmp.right
        else:
            pre.right = tmp.right
    else:
        if par.left == node:
            par.left = None
        else:
            par.right = None
    return root



6/3 829. 连续整数求和

n是否可以表示成k个连续整数之和
如果k是奇数 且n能被k整除 则可以
如果k是偶数 且n不能被k整除 且2n可以被k整除时 可以


def consecutiveNumbersSum(n):
    """
    :type n: int
    :rtype: int
    """
    def find(k):
        if k%2==1:
            return n%k==0
        return n%k and 2*n%k==0
    ans = 0
    k = 1
    while k*(k+1)<=2*n:
        if find(k):
            print(k)
            ans +=1
        k+=1
    return ans


6/4 929. 独特的电子邮件地址

哈希表m记录不一样的地址
将本地名处理后记录结果目标地址



def numUniqueEmails(emails):
    """
    :type emails: List[str]
    :rtype: int
    """
    m = {}
    for email in emails:
        l = email.split('@')
        loc = l[0]
        loc = loc.split('+')[0]
        loc = loc.replace('.','')
        m[loc+"@"+l[1]] = 1
    return len(m)


6/5 478. 在圆内随机生成点

对于半径为r的圆 随机在[-r,r]的正方形中取点(x,y)
如果x,y在圆内即可 圆内每个点出现的概率相同

class Solution(object):

    def __init__(self, radius, x_center, y_center):
        """
        :type radius: float
        :type x_center: float
        :type y_center: float
        """
        self.xc = x_center
        self.yc = y_center
        self.r = radius


    def randPoint(self):
        """
        :rtype: List[float]
        """
        import random
        while True:
            x,y = random.uniform(-self.r,self.r),random.uniform(-self.r,self.r)
            if x*x+y*y<=self.r*self.r:
                return [self.xc+x,self.yc+y]



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值