LeetCode 將一個按照升序排列的有序數組,轉換爲一棵高度平衡二叉搜索樹

第108題java

將一個按照升序排列的有序數組,轉換爲一棵高度平衡二叉搜索樹。

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

示例:

給定有序數組: [-10,-3,0,5,9],

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

      0
     / \
   -3   9
   /   /
 -10  5

來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree

解題思路

  • 從定義咱們知道,BST的中序遍歷爲一個遞增序列,給定的數組其實就是中序遍歷結果
  • 取有序數組的中間值作根,左邊部分作左樹,右邊部分作右樹如此循環迭代去二分就可還原這棵BST樹

代碼實現

1.二分+遞歸實現

每次取數組的中間值,做爲二分搜索樹的中間節點,依次遞歸下去便可node

//二分+遞歸實現
class Solution108_1 {
    public TreeNode sortedArrayToBST(int[] nums) {
        return convertToBST(nums, 0, nums.length - 1);
    }

    TreeNode convertToBST(int[] nums, int begin, int end) {
        if (begin > end) return null;
        //取中值
        int mid = begin + (end - begin) / 2;
        TreeNode root = new TreeNode(nums[mid]);
        //左葉子樹
        root.left = convertToBST(nums, begin, mid - 1);
        //右葉子樹
        root.right = convertToBST(nums, mid + 1, end);
        return root;
    }
}

2.利用堆棧,去遞歸化實現

  • 定義一個棧,用來存將要處理數組的左索引和右索引值
  • 定義另外一個棧,用來存樹的節點,由於節點是先初始化,後更新節點值的迭代過程。因此須要借用堆棧先建好節點,創建好關係。
//非遞歸實現
class Solution108_2 {
    public TreeNode sortedArrayToBST(int[] nums) {
        if (nums == null || nums.length == 0) return null;
        Stack<Integer> stack = new Stack<Integer>();
        //數組最大索引值入棧
        stack.add(nums.length - 1);
        //數組最小索引值入棧
        stack.add(0);

        Stack<TreeNode> tree = new Stack<TreeNode>();
        TreeNode root = new TreeNode(0);
        //隨便new樹節點入棧
        tree.add(root);

        while (!stack.isEmpty()) {
            int left = stack.pop();
            int right = stack.pop();
            //求出中間節點索引值
            int mid = left + (right - left) / 2;
            TreeNode node = tree.pop();
            //更新根節點值
            node.val = nums[mid];

            //計算左葉子節點最大最小索引值
            int r = mid - 1, l = left;
            //若是存在左葉子節點
            if (l <= r) {
                node.left = new TreeNode(0);
                //隨便new個樹節點入棧
                tree.add(node.left);

                //對應右索引值入棧
                stack.push(r);
                //對應左索引值入棧
                stack.push(l);
            }

            //計算右節點最大最小索引值
            l = mid + 1;
            r = right;
            if (l <= r) {
                node.right = new TreeNode(0);
                //隨便new個樹節點入棧
                tree.add(node.right);

                //對應右索引值入棧
                stack.push(r);
                //對應左索引值入棧
                stack.add(l);
            }
        }
        return root;
    }
}

總結

不出所料,經過提交代碼發現堆棧實現會比遞歸執行效率慢不少,這是由於:git

  • 堆棧實現須要頻繁的push(入棧)、pop(出棧)操做致使性能降低

資料

相關文章
相關標籤/搜索