LeetCode 每日一题 2024/4/1-2024/4/7

文章介绍了如何解决一系列与树结构(如故障键盘插入顺序、真二叉树构建、克隆二叉树相同节点查找、有向无环图祖先查询、节点差值计算及树节点第K个祖先)以及图论(王位继承顺序)相关的问题,通过递归和深度优先搜索等方法进行求解。
摘要由CSDN通过智能技术生成

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




4/1 2810. 故障键盘

依次考虑 将字符串放入数组中
记录插入的位置如果逆序 则从头开始插入
loc记录是顺序还是逆序

def finalString(s):
    """
    :type s: str
    :rtype: str
    """
    loc =True
    ans=[]
    for c in s:
        if c=="i":
            loc = not loc
        elif loc:
            ans.append(c)
        else:
            ans = [c]+ans
    if loc:
        return ''.join(ans)
    else:
        return ''.join(ans[::-1])



4/2 894. 所有可能的真二叉树

真二叉树总结点必定为奇数
mem[i]记录i个节点的真二叉树情况

class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
def allPossibleFBT(n):
    """
    :type n: int
    :rtype: List[TreeNode]
    """
    if n<3 or n%2==0:
        return []
    mem = {}
    mem[1] = [TreeNode(0)]
    def check(num):
        if num in mem:
            return mem[num]
        tmp = []
        for l in range(1,num-1,2):
            left = check(l)
            right = check(num-1-l)
            
            for ln in left:
                node = TreeNode(0)
                node.left = ln
                for rn in right:
                    node.right = rn
                    tmp.append(node)
        mem[num]=tmp
        return tmp
    return check(n)



4/3 1379. 找出克隆二叉树中的相同节点

dfs搜索

class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
def getTargetCopy(original, cloned, target):
    """
    :type original: TreeNode
    :type cloned: TreeNode
    :type target: TreeNode
    :rtype: TreeNode
    """
    def check(ori,clo):
        if not ori:
            return ori
        if ori==target:
            return clo
        left = check(ori.left,clo.left)
        right = check(ori.right,clo.right)
        if left:
            return left
        return right
    return check(original, cloned)



4/4 2192. 有向无环图中一个节点的所有祖先

如果x为y的祖先 那么x的祖先必定是y的祖先
cur存储祖先节点已经都被考虑过的节点
par[x]记录x当前未被考虑的祖先个数
ans[x]记录x的祖先

def getAncestors(n, edges):
    """
    :type n: int
    :type edges: List[List[int]]
    :rtype: List[List[int]]
    """
    cur = set(list(range(n)))
    ans = [set() for _ in range(n)]
    m = [[] for _ in range(n)]
    par = [0]*n
    for x,y in edges:
        if y in cur:
            cur.remove(y)
        m[x].append(y)
        par[y]+=1
    while cur:
        tmp = set()
        for p in cur:
            for child in m[p]:
                ans[child].add(p)
                ans[child]|=ans[p]
                par[child]-=1
                if par[child]==0:
                    tmp.add(child)
        cur = tmp
    for i in range(n):
        ans[i] = sorted(list(ans[i]))
    return ans



4/5 1026. 节点与其祖先之间的最大差值

从根节点往子节点判断 记录当前最大值和最小值
当前节点与最大值最小值能够得到的最大差值

class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
def maxAncestorDiff(root):
    """
    :type root: TreeNode
    :rtype: int
    """
    global ans
    ans = 0
    def check(node,minv,maxv):
        global ans
        if not node:
            return
        ans = max(ans,abs(minv-node.val))
        ans = max(ans,abs(maxv-node.val))
        minv = min(node.val,minv)
        maxv = max(node.val,maxv)
        check(node.left,minv,maxv)
        check(node.right,minv,maxv)
    check(root,root.val,root.val)
    return ans



4/6 1483. 树节点的第 K 个祖先

dp[i]用来记录i的祖先
因为n很大 使用二维dp[i][j] 记录i的第2^j个祖先
dp[i][0]即为i的父节点
dp[i][j] = dp[dp[i][j-1]][j-1]
即i的第2^j个祖先 是i的第2^(j-1) 个祖先的第2^(j-1)个祖先

class TreeAncestor(object):
    
    def __init__(self, n, parent):
        """
        :type n: int
        :type parent: List[int]
        """
        self.dp = [[] for _ in range(n)]
        
        for i in range(n):
            self.dp[i].append(parent[i])
        j=1
        while True:
            tag = True
            for i in range(n):
                v = -1
                if self.dp[i][j-1]!=-1:
                    v = self.dp[self.dp[i][j-1]][j-1]
                self.dp[i].append(v)
                if v!=-1:
                    tag = False
            if tag:
                break
            j+=1      


    def getKthAncestor(self, node, k):
        """
        :type node: int
        :type k: int
        :rtype: int
        """
        ans = node 
        pos = 0
        while k and ans!=-1:
            if pos>=len(self.dp[ans]):
                return -1
            if k&1:
                ans = self.dp[ans][pos]
            k = k>>1
            pos+=1
        return ans



4/7 1600. 王位继承顺序

可以看做是一个多叉树
继承顺序为父-子 前序遍历 根左右
dead记录死亡的人
m[x]记录x的儿子

class ThroneInheritance(object):

    def __init__(self, kingName):
        """
        :type kingName: str
        """
        from collections import defaultdict
        self.dead = set()
        self.king = kingName
        self.m = defaultdict(list)


    def birth(self, parentName, childName):
        """
        :type parentName: str
        :type childName: str
        :rtype: None
        """
        self.m[parentName].append(childName)


    def death(self, name):
        """
        :type name: str
        :rtype: None
        """
        self.dead.add(name)


    def getInheritanceOrder(self):
        """
        :rtype: List[str]
        """
        ans = []
        def pre(name):
            if name not in self.dead:
                ans.append(name)
            if name in self.m:
                for c in self.m[name]:
                    pre(c)
        pre(self.king)
        return ans



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值