【算法】樹

二叉樹深度優先遍歷:先序遍歷,中序遍歷,後序遍歷的遞歸與非遞歸。

二叉樹廣度優先遍歷:層次遍歷。

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

#遞歸前序
def preTran(head):
    if head is not None:
        print(head.val)
        preTran(head.left)
        preTran(head.right)

#遞歸中序
def midTran(head):
    if head is not None:
        midTran(head.left)
        print(head.val)
        midTran(head.right)

#遞歸後序
def postTran(head):
    if head is not None:
        postTran(head.left)
        postTran(head.right)
        print(head.val)

#非遞歸前序
def preTranStack(head):
    if head is None:
        return
    p = head
    stack = []
    while p is not None or len(stack) > 0:
        if p is not None:
            print(p.val)
            stack.append(p)
            p = p.left
        else:
            p = stack.pop()
            p = p.right

#非遞歸中序
def midTranStack(head):
    if head is None:
        return
    p = head
    stack = []
    while p is not None or len(stack) > 0:
        if p is not None:
            stack.append(p)
            p = p.left
        else:
            p = stack.pop()
            print(p.val)
            p = p.right

#非遞歸後序
def postTranStack(head):
    if head is None:
        return
    cur = head
    pre = 0
    stack = [cur]
    while len(stack) > 0:
        cur = stack[-1]
        if (cur.left is None and cur.right is None) or (pre == cur.left) or (pre == cur.right):
            cur = stack.pop()
            print(cur.val)
            pre = cur
        else:
            if cur.right is not None:
                stack.append(cur.right)
            if cur.left is not None:
                stack.append(cur.left)

#廣度優先,or層次遍歷
def BFS(head):
    p = head
    queue = [p]
    while len(queue) > 0:
        p = queue.pop(0)
        print(p.val)
        if p.left is not None:
            queue.append(p.left)
        if p.right is not None:
            queue.append(p.right)

1. 對稱二叉樹

判斷一個樹是否是對稱的。(遞歸)

def sym(head):
    if head is None:
        return True
    else:
        return cmp(head.left, head.right)
def cmp(left,right):
    if left is None and right is None:
        return True
    elif left is None or right is None:
        return False
    elif left.val != right.val:
        return False
    else:
        return cmp(left.left, right.right) and cmp(left.right, right.left)

2. 鏡像二叉樹(遞歸)

def mirrorTree(head):
    if head is None or (head.left is None and head.right is None):
        return
    else:
        temp = head.left
        head.left = head.right
        head.right = temp
        if head.left:
            mirrorTree(head.left)
        if head.right:
            mirrorTree(head.right)

3. 二叉樹深度(遞歸)

def depthTree(head):
    if head is None:
        return 0
    else:
        return 1+ max(depthTree(head.left), depthTree(head.right))

4. 二叉樹寬度(層次遍歷二叉樹,逐行打印二叉樹):

def widthTree(head):
    res = []
    width = 0
    if head is None:
        return 0
    queue = [head]
    while len(queue) > 0:
        res.append([i.val for i in queue])
        width = len(queue)
        for i in range(len(queue)):
            p = queue.pop(0)
            if p.left:
                queue.append(p.left)
            if p.right:
                queue.append(p.right)
    return width

5. 平衡二叉樹(遞歸)

一棵樹,若左右子樹高度差不超過1,則爲平衡二叉樹

def balance(head):
    if head is None:
        return True
    if abs(depthTree(head.left) - depthTree(head.right)) > 1:
        return False
    return balance(head.left) and balance(head.right)

6. 重建二叉樹(已知前序,中序)(遞歸)

def rebuild(pre,mid):
    if len(pre) == 0:
        return 
    if len(pre) == 1:
        return TreeNode(pre[0])
    index = mid.index(pre[0])
    t = TreeNode(pre[0])
    t.left = rebuild(pre[1:index + 1], mid[:index])
    t.right = rebuild(pre[index+1:], mid[index+1:])
    return t

7. 二叉搜索樹(二叉排序樹)第k個節點

二叉搜索樹:左子樹>跟>右子樹,與中序遍歷對應

class Solution:
    # 返回對應節點TreeNode,中序遍歷即可
    def __init__(self):
        self.result = []
    def KthNode(self, pRoot, k):
        if k <= 0:
            return None
        else:
            self.midsort(pRoot)
            if k > len(self.result):
                return None
            return self.result[k-1]
        
    def midsort(self, p):
        if p == None:
            return None
        else:
            self.midsort(p.left)
            self.result.append(p)
            self.midsort(p.right)

8. 二叉搜索樹後序遍歷

判斷某序列是否爲二叉搜索樹後續遍歷的結果。

class Solution:
    def VerifySquenceOfBST(self, sequence):
        # 二叉搜索樹後序序列,最後一個節點是根節點,剩下的可以分成兩個序列
        #左邊的都比根小,右邊的都比根大
        if sequence == []:
            return False
        return self.judge(sequence)
    
    def judge(self,sequence):
        if len(sequence) == 0:
            return True
        root = sequence.pop(-1)
        left = [i for i in sequence if i < root]
        right = [i for i in sequence if i > root]
        if left +right == sequence:
            return self.judge(left) and self.judge(right)
        else:
            return False

9. 完全二叉樹的判斷

class CheckCompletion:
    def chk(self, root):
        # write code here
        if root is None:
            return True
        q = [root]
        flag = False #當爲True時,表示此節點之後的所有節點都爲葉子節點
        while q != []:
            cur = q.pop(0)
            if flag == True:
                if cur.left or cur.right:
                    return False
                else:
                    continue
            else:
                if cur.left and cur.right:
                    q.append(cur.left)
                    q.append(cur.right)
                if cur.left and not cur.right:
                    flag = True
                if not cur.left and cur.right:
                    return False
        return True

10. 最大二叉搜索子樹

class MaxSubtree:
    def __init__(self):
        self.max = -999999999999
        self.min = 999999999999
        self.num = 0
    def getMax(self, root):
        if root is None:
            self.max = -999999999999
            self.min = 999999999999
            self.num = 0
            return None
        lnode = self.getMax(root.left)
        lmax = self.max
        lmin = self.min
        lnum = self.num
        rnode = self.getMax(root.right)
        rmax = self.max
        rmin = self.min
        rnum = self.num
        self.max = max(root.val, rmax)
        self.min = min(root.val, lmin)
        if lnode == root.left and rnode == root.right and lmax < root.val and rmin > root.val:
            self.num = lnum+rnum + 1
            return root
        else:
            if lnum > rnum:
                self.num = lnum
                return lnode
            else:
                self.num = rnum
                return rnode

11. 樹上兩點間最長距離(最長路徑長度)

class LongestDistance:
    def __init__(self):
        self.res = 0
    def findLongest(self, root):
        # write code here
        self.find(root)
        return self.res
    
    def find(self,root):
        if root is None:
            return 0
        left = self.find(root.left)
        right = self.find(root.right)
        self.res = max(left+right+1,self.res)
        return max(left,right)+1

12. 二叉樹最大路徑和(包括節點值)

https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/submissions/

class Solution(object):
    def maxPathSum(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        self.res = -float('inf') #這裏要設爲負無窮
        self.dfs(root)
        return self.res
    
    def dfs(self, root):
        if root is None:
            return 0
        left = max(0, self.dfs(root.left))
        right = max(0, self.dfs(root.right))
        self.res = max(left+right+root.val, self.res)
        return max(left, right) + root.val

13. 求樹上根到葉子節點所有的路徑

https://leetcode-cn.com/problems/binary-tree-paths/submissions/ 

https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/submissions/

class Solution(object):
    def binaryTreePaths(self, root):
        """
        :type root: TreeNode
        :rtype: List[str]
        """
        if root is None:
            return []
        res = []
        self.dfs(root, res, str(root.val))
        return res
    
    def dfs(self, root, res, string):
        if root.left is None and root.right is None:
            res.append(string)
        if root.left:
            self.dfs(root.left, res, string + "->" + str(root.left.val))
        if root.right:
            self.dfs(root.right, res, string + "->" +str(root.right.val))
        return

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章