經典算法-二叉樹(golang)


package main

func main() {

}

//Definition for a binary tree node.
type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

// 938. Range Sum of BST  二叉搜索樹的范圍和
//Input: root = [10,5,15,3,7,null,18], L = 7, R = 15    Output: 32
//Input: root = [10,5,15,3,7,13,18,1,null,6], L = 6, R = 10    Output: 23
func rangeSumBST(root *TreeNode, L int, R int) int {
    if root == nil {
        return 0
    }
    if root.Val > R {
        return rangeSumBST(root.Left, L, R)
    }
    if root.Val < L {
        return rangeSumBST(root.Right, L, R)
    }
    return root.Val + rangeSumBST(root.Left, L, R) + rangeSumBST(root.Right, L, R)
}


// 617. Merge Two Binary Trees    合並二叉樹
//Input:
//        Tree 1                  Tree 2
//         1                         2
//        / \                       / \
//       3   2                     1   3
//      /                           \   \
//   5                             4   7
//Output:
//        Merged tree:
//               3
//              / \
//             4   5
//            / \   \
//            5   4   7
func mergeTrees(t1 *TreeNode, t2 *TreeNode) *TreeNode {
    if t1 == nil { // 如果t1為空,t2非空,那么我們就以t2的結點值建立一個新結點
        return t2
    }
    if t2 == nil { // 如果t2為空,t1非空,那么我們就以t1的結點值建立一個新結點
        return t1
    }
    // 如果t1和t2都非空,那么我們就以t1和t2的結點值之和建立一個新結點,然后分別對t1的左右子結點和t2的左右子結點調用遞歸函數
    return &TreeNode{t1.Val + t2.Val, mergeTrees(t1.Left, t2.Left), mergeTrees(t1.Right, t2.Right)}
}

// 104. Maximum Depth of Binary Tree    求二叉樹最大深度
// 思路:很簡單,當前結點深度等於左右子樹中較大的那個深度加一。
func maxDepth(root *TreeNode) int {
    if root == nil {
        return 0
    }
    left := maxDepth(root.Left)
    right := maxDepth(root.Right)
    if left > right {
        return left + 1
    } else {
        return right + 1
    }

}
//求二叉樹最小深度
//算法參照二叉樹的最大深度,這里需要注意的是當某節點的左右孩子都存在時,就返回左右子樹的最小深度;
//如果不都存在,就需要返回左右子樹的最大深度(因為子節點不存在的話,通向該子樹的路徑就走不同,就不存在深度,也無法比較。
//只能從另一子樹方向走。)如果左右孩子不都存在時還取小值,那返回的就是父節點的深度,會出錯。
func minDepth(root *TreeNode) int {
    if root == nil {
        return 0
    }
    left := minDepth(root.Left)
    right := minDepth(root.Right)
    if left == 0 || right == 0 {
        return left + right + 1
    }
    if left > right {
        return right + 1
    } else {
        return left + 1
    }
}
 
         

 

// 226. Invert Binary Tree    反轉二叉樹
// 思路:遞歸互換左右子節點
//Example:
//
//Input:                        Output:
//
//        4                          4
//      /   \                        /   \
//      2    7                   7     2
//     / \   / \                  / \   / \
//    1   3 6   9                 9   6 3   1
func invertTree(root *TreeNode) *TreeNode {
    if root == nil {
        return root
    }
    root.Left, root.Right = invertTree(root.Right), invertTree(root.Left)
    return root
}

// TODO 判斷兩棵樹是否相等
func isEqual(r1, r2 *TreeNode) bool {
    if r1 == nil && r2 == nil {
        return true
    }
    if r1 == nil || r2 == nil {
        return false
    }
    if r1.Val == r2.Val {
        return isEqual(r1.Left, r2.Right) && isEqual(r1.Right, r2.Right)
    }
    return false
}
 
         
// 538. Convert BST to Greater Tree        二叉查找樹轉化為更大樹
// 思路:二叉查找樹右邊子節點比節點數值大,遞歸所有右節點的累加和 右-中-左遍歷相加
func convertBST(root *TreeNode) *TreeNode {
    node, _ := traverse(root, 0)
    return node
}

func traverse(root *TreeNode, sum int) (*TreeNode, int) {
    if root == nil {
        return nil, sum
    }

    _, sum = traverse(root.Right, sum)
    root.Val += sum
    sum = root.Val
    _, sum = traverse(root.Left, sum)

    return root, sum
}

// 230.給定一個二叉搜索樹,請找出其中第k小的節點。 
// 中序遍歷

func kthSmallest(root *TreeNode, k int) int {
    if root == nil {
        return 0
    }
    var sum, num int
    var inOrder func(root *TreeNode)
    inOrder = func(root *TreeNode) {
        if root == nil {
            return
        }
        inOrder(root.Left)
        num++
        if num == k {
            sum = root.Val
            return
        }
        inOrder(root.Right)
    }
    inOrder(root)
    return sum
}


// 給定一棵二叉搜索樹,請找出其中第k大的節點。 
// 中序遍歷反着來:后-中-左

func kthLargest(root *TreeNode, k int) int {
    var num, sum int
    var inOrder func(root *TreeNode)
    inOrder = func(root *TreeNode) {
        if root == nil {
            return
        }
        inOrder(root.Right)
        num++
        if num == k {
            sum = root.Val
            return
        }
        inOrder(root.Left)
    }
    inOrder(root)
    return sum
}
// 98. 給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹。 
// 中序遍歷

var lastNode *TreeNode
func isValidBST(root *TreeNode) bool {
    lastNode = nil
    return inOrder(root)
}

func inOrder(root *TreeNode) bool {
    if root == nil {
        return  true
    }
    if !inOrder(root.Left) {
        return false
    }
    if lastNode != nil && lastNode.Val >= root.Val {
        return false
    }
    lastNode = root
    return inOrder(root.Right)
}


// 55. 給定一個二叉樹,判斷該樹是不是平衡二叉樹
func isBalanced(root *TreeNode) bool {
    if root == nil {
        return true
    }
    if maxDepth(root.Left) - maxDepth(root.Right) > 1 || maxDepth(root.Right) - maxDepth(root.Left) > 1 {
        return     false
    }
    return isBalanced(root.Left) && isBalanced(root.Right)

}
func maxDepth(root *TreeNode) int {
    if root == nil {
        return 0
    }
    left, right := maxDepth(root.Left), maxDepth(root.Right)
    if left > right {
        return left + 1
    }
    return right + 1
}

 

// 從上到下按層打印二叉樹
//例如:
//給定二叉樹: [3,9,20,null,null,15,7],
//		3
//	   / \
//	  9  20
//   /  \
// 15   7
//返回其層次遍歷結果:
//
//[
//[3],
//[9,20],
//[15,7]
//]
func levelOrder(root *TreeNode) [][]int {
	if root == nil {
		return nil
	}
	var arr [][]int
	q := []*TreeNode{root}
	for len(q) > 0 {
		temp := make([]int, len(q))
		length := len(q)
		for ; length >= 0; length-- {
			if q[0].Left != nil {
				q = append(q, q[0].Left)
			}
			if q[0].Right != nil {
				q = append(q, q[0].Right)
			}
			temp = append(temp, q[0].Val)
			q = q[1:]
		}
		arr = append(arr, temp)
	}
	return arr
}
// 按照之字形打印二叉樹
// 第一行按照從左到右的順序打印,第二層按照從右至左的順序打印,依次類推
func printTreeNode(root *TreeNode) [][]int {
	if root == nil {
		return nil
	}
	var arr [][]int
	q := []*TreeNode{root}
	for level := 0; len(q) > 0; level++ {
		length := len(q)
		temp := make([]int, length)
		if level&0x1 == 0 {
			for i := 0; i < length; i++ {
				temp = append(temp, q[i].Val)
			}
		} else {
			for i := length; i >= 0; i-- {
				temp = append(temp, q[i].Val)
			}
		}
		arr = append(arr, temp)
		for ; length >= 0; length-- {
			if q[0].Left != nil {
				q = append(q, q[0].Left)
			}
			if q[0].Right != nil {
				q = append(q, q[0].Right)
			}
			q = q[1:]
		}
		arr = append(arr, temp)
	}
	return arr
}

  

  

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM