LeetCode-深度优先搜索-Medium

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




98. 验证二叉搜索树

解题思路:
二叉搜索树 左边<根<右边
可以使用中序遍历LNR即左根右 若符合二叉搜索树 则遍历得到的是从小到大的序列
注意 如果出现相同值 那么就不符合二叉搜索树

def isValidBST(root):
    """
    :type root: TreeNode
    :rtype: bool
    """
    if not root:
        return True

    def LNR(node):
        ret = []
        if node.left!=None:
            ret.extend(LNR(node.left))
        ret.append(node.val)
        if node.right!=None:
            ret.extend(LNR(node.right))
        return ret
        
    l = LNR(root)
    l2 = sorted(l)
    l3 = list(set(l))
    if l==l2 and len(l)==len(l3):
        return True
    else:
        return False

105. 从前序与中序遍历序列构造二叉树

解题思路1:
根据手工画二叉树的思路
若前序pre = ABCDE 中序in=BADCE
STEP 1,前序:根左右,第一个一定是根->A|BCDE
STEP 2,中序:左根右,知道了根的位置可以划分出左子树和右子树B|A|DCE
STEP 3,回到前序可以知道左右子树的前序遍历A|B|CDE
再如此分别处理左右子树

def buildTree(preorder, inorder):
    """
    :type preorder: List[int]
    :type inorder: List[int]
    :rtype: TreeNode
    """
    rootvalue = preorder[0]
    root = TreeNode(rootvalue)
    rootinpos = inorder.index(rootvalue)
    leftin = inorder[:rootinpos]
    rightin = inorder[rootinpos+1:]
    lenleft = len(leftin)
    leftpre = preorder[1:1+lenleft]
    rightpre = preorder[1+lenleft:]
    
    rightnode = buildTree(rightpre,rightin)
    leftnode = buildTree(leftpre,leftin)
    
    root.left = leftnode
    root.right = rightnode
    
    return root

解题思路2:
和思路一一样但是实现上进行了优化
根据中序遍历将每一个节点进行标号
在前序遍历中每次取第一个根节点
根据该根节点在中序遍历中的位置可以知道
在其前面的一定是其左子树,后面的则是右子树
递归

def buildTree(preorder, inorder):
    """
    :type preorder: List[int]
    :type inorder: List[int]
    :rtype: TreeNode
    """
    n = len(inorder)
    indic = dict(zip(inorder,range(n)))
    
    def create(i, j):
        if i > j: return None
        root = TreeNode(preorder.pop(0))
        iroot = indic[root.val]
        root.left = create(i,iroot-1)
        root.right = create(iroot+1, j)
        return root
    return create(0, n - 1)

106. 从中序与后序遍历序列构造二叉树

解题思路:
和105的思路一致
因为是后序 所以每次取其最后一个节点为根节点

def buildTree(inorder,postorder):
    """
    :type preorder: List[int]
    :type inorder: List[int]
    :rtype: TreeNode
    """
    if len(postorder)==0 or len(inorder)==0:
        return None
    
    n = len(inorder)
    indic = dict(zip(inorder,range(n)))
    
    def create(i, j):
        if i > j: return None
        root = TreeNode(postorder.pop())
        iroot = indic[root.val]
        root.right = create(iroot+1, j)
        root.left = create(i, iroot-1)
        return root
    return create(0, n - 1)

109. 有序链表转换二叉搜索树

解题思路:
将链表变为list
回归108题 0.0

def sortedListToBST(head):
    """
    :type head: ListNode
    :rtype: TreeNode
    """
    l =[]
    while head!=None:
        l.append(head.val)
        head = head.next
    def sortedArrayToBST(nums):
        if len(nums)==0:
            return None
        pos = len(nums)//2
        node = TreeNode(nums[pos])
        if pos:
            node.left = sortedArrayToBST(nums[:pos])
            node.right = sortedArrayToBST(nums[pos+1:])
            return node
        else:
            return node
    
    ret = sortedArrayToBST(l)
    return ret

113. 路径总和 II

解题思路1:
穷举 列出所有的路径后 挑选符合路径

def pathSum(root, sum):
    """
    :type root: TreeNode
    :type sum: int
    :rtype: List[List[int]]
    """
    ret =[]
    r = []
    if root==None:
        return ret
    def allpath(node,l):
        l.append(node.val)
        if node.left==None and node.right==None:
            r.append(l)
        if node.left!=None:
            allpath(node.left,l[:])
        if node.right!=None:
            allpath(node.right,l[:])
    def s(l):
        ret =0
        for i in l:
            ret+=i
        return ret
    allpath(root,[])  
    for v in r:
        if s(v)==sum:
            ret.append(v)
    return ret

解题思路2:
递归
如果节点为叶节点 并且剩下的值与该节点的值一致 则找到一条路径
将这条路径添加 返回后根节点会将自己的值加入其中
如果没有路径 则list中没有结果

def pathSum(root, sum):
    """
    :type root: TreeNode
    :type sum: int
    :rtype: List[List[int]]
    """
    ret =[]
    if root==None:
        return ret
    if root.left==None and root.right==None:
        if root.val==sum:
            return [[root.val]]
        else:
            return []
    
    l = pathSum(root.left,sum-root.val)
    r = pathSum(root.right,sum-root.val)
    llist = [[root.val]+i for i in l]
    rlist = [[root.val]+i for i in r]
    return llist+rlist

114. 二叉树展开为链表

解题思路:
递归 分别处理左子树 右子树
将左子树的叶节点指向根节点的右子树
再将根节点的右边指向左子树的头结点

def flatten(root):
    """
    :type root: TreeNode
    :rtype: void Do not return anything, modify root in-place instead.
    """
    if not root:
        return
    if root.left:
        flatten(root.left)
    if root.right:
        flatten(root.right)
    head = root.left
    tmpleft = root.left
    while tmpleft and tmpleft.right:
        tmpleft = tmpleft.right

    if tmpleft:
        tmpleft.right = root.right
    if head:     
        root.right = head
    root.left = None

    return root

129. 求根到叶子节点数字之和

解题思路:
从根开始 将父节点已有的值传给子节点

def sumNumbers(root):
    """
    :type root: TreeNode
    :rtype: int
    """
    return sumnum(root,0)
        
def sumnum(root,presum):
    if root == None:
        return 0
    presum = presum *10 + root.val
    
    if root.left==None and root.right==None:
        return presum
    
    return sumnum(root.left,presum) + sumnum(root.right,presum)

猜你喜欢

转载自blog.csdn.net/zkt286468541/article/details/83212442