1. 程式人生 > 實用技巧 >leetcode刷題筆記一百零九題 有序連結串列轉換二叉搜尋樹

leetcode刷題筆記一百零九題 有序連結串列轉換二叉搜尋樹

leetcode刷題筆記一百零九題 有序連結串列轉換二叉搜尋樹

源地址:109. 有序連結串列轉換二叉搜尋樹

問題描述:

給定一個單鏈表,其中的元素按升序排序,將其轉換為高度平衡的二叉搜尋樹。

本題中,一個高度平衡二叉樹是指一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。

示例:

給定的有序連結串列: [-10, -3, 0, 5, 9],

一個可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面這個高度平衡二叉搜尋樹:

 0
/ \

-3 9
/ /
-10 5

/**
本題在108題的基礎上,進行了延伸,核心思想與108題基本一致,即獲取區間的中間節點,作為根節點,遞迴其左子樹區間與右子樹區間。這裡提供兩種解法,快慢指標法和利用中序遍歷思想
*/
//快慢指標,快指標每次向前2步,慢指標每次向前1步,這樣當快指標到末尾時,慢指標正好指向中間結點
/**
 * Definition for singly-linked list.
 * class ListNode(var _x: Int = 0) {
 *   var next: ListNode = null
 *   var x: Int = _x
 * }
 */
/**
 * Definition for a binary tree node.
 * class TreeNode(var _value: Int) {
 *   var value: Int = _value
 *   var left: TreeNode = null
 *   var right: TreeNode = null
 * }
 */
object Solution {
    def sortedListToBST(head: ListNode): TreeNode = {
        def helper(head: ListNode): TreeNode = {
            if (head == null) return null
            if (head.next == null){
                return new TreeNode(head.x)
            }

            var prev:ListNode = null
            var slow = head
            var fast = head

            while (fast != null && fast.next != null){
                prev = slow
                slow = slow.next
                fast = fast.next.next
            }

            prev.next = null

            val root = new TreeNode(slow.x)
            root.left = helper(head)
            root.right = helper(slow.next)
            return root
        }
        return helper(head)
    }
}

//基於中序遍歷的遞迴,基於先左後右的原則,且整個陣列有序,故陣列第一個節點為最左側結點,則遞迴位置與結點順序一致
/**
 * Definition for singly-linked list.
 * class ListNode(var _x: Int = 0) {
 *   var next: ListNode = null
 *   var x: Int = _x
 * }
 */
/**
 * Definition for a binary tree node.
 * class TreeNode(var _value: Int) {
 *   var value: Int = _value
 *   var left: TreeNode = null
 *   var right: TreeNode = null
 * }
 */
object Solution {
    def sortedListToBST(head: ListNode): TreeNode = {
		//獲取結點個數
        var length = 0
        var startHelper = head
        while (startHelper != null){
            startHelper = startHelper.next
            length += 1
        }
        
        var start = head
        
        def helper(left: Int, right: Int): TreeNode = {
            if (left > right) return null
            val mid = (right + left + 1)/2
            //先遞迴左側,因為此時指標指向的永遠是當前樹中最左側結點
            val leftTree = helper(left, mid-1)
            //構建樹
            val root = new TreeNode(start.x)
            root.left = leftTree
            start = start.next
            root.right = helper(mid+1, right)
            return root
    }
    return helper(0, length-1) 
  }
}