zoukankan      html  css  js  c++  java
  • 177 把排序数组转换为高度最小的二叉搜索树

    原题网址:https://www.lintcode.com/problem/convert-sorted-array-to-binary-search-tree-with-minimal-height/description

    描述

    给一个排序数组(从小到大),将其转换为一棵高度最小的排序二叉树。

    There may exist multiple valid solutions, return any of them.

    您在真实的面试中是否遇到过这个题?  

    样例

    给出数组 [1,2,3,4,5,6,7], 返回

         4
       /   
      2     6
     /     / 
    1   3  5   7

    标签
    二叉树
    递归
    Cracking The Coding Interview
     
    思路:二叉树问题日常懵比……最开始想的是从头开始遍历数组,一个节点一个节点的建立二叉树,后来,后来当然是做不下去了……
    在网上看了别人的答案后有了思路,自己把代码写了出来,总结下:创建二叉树应该先建立根节点,再挂载左右孩子。而不是先创建左右孩子再记录更新根节点。
     
    嗯……要创建二叉搜索树首先要创建根节点,哪个元素是根节点呢?
    二叉搜索树的定义:它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。   转自此文
     
    所以根节点应该是数组索引中间值,左边的元素是左子树,右边的元素是右子树。对左右子树的创建也是同理,先创建根节点(中间值),二分后左边元素是左子树,右边元素是右子树,重复这个二分过程直到所有元素创建完毕。以上思路可用递归来实现。(树的很多问题都是递归啊)
     
    AC代码:
    /**
     * Definition of TreeNode:
     * class TreeNode {
     * public:
     *     int val;
     *     TreeNode *left, *right;
     *     TreeNode(int val) {
     *         this->val = val;
     *         this->left = this->right = NULL;
     *     }
     * }
     */
    
    
    class Solution {
    public:
        /*
         * @param A: an integer array
         * @return: A tree node
         */
        TreeNode * sortedArrayToBST(vector<int> &A) {
            // write your code here
        if (A.empty())
        {
            return NULL;
        }
    
        int ed=A.size()-1;
        int mid=ed/2;
        TreeNode * newroot=builtTree(A,0,ed);
    
        return newroot;
        }
        
        TreeNode * builtTree(vector<int> &A,int st,int ed)
    {
        if (st>ed)
            {
                return NULL;
            }
        int mid=(st+ed)/2;
        TreeNode * newroot=new TreeNode(A[mid]);
        newroot->left=builtTree(A,st,mid-1);
        newroot->right=builtTree(A,mid+1,ed);
        return newroot;
    }
    };

    此外,对于这种牵涉数组首尾位置的运算,最好能令首尾位置作为形参参与运算。例如之前我们见到的“搜索区间”的问题(详见:点击打开链接)就是在求左右两侧的界限时,将数组一分为二,分别令首尾位置作为形参。这是一种标准的解决办法!

    那么,这道题就不难了,也采取定义新的辅助函数的方法,将首尾位置作为形参。   转自此文

    其他参考:https://blog.csdn.net/lfj17/article/details/70146866

    https://blog.csdn.net/yaomf/article/details/70257108

    https://blog.csdn.net/lyy_hit/article/details/49660671

     
    PS:参考里的答案都是在sortedArrayToBST 函数里先创建根节点,再调用递归函数:

    TreeNode *newroot=new TreeNode(A[mid]);//第一个节点;
    newroot->left=builtTree(A,0,mid-1);
    newroot->right=builtTree(A,mid+1,ed);

    而我是直接调用递归函数。区别大概就是返回的根节点是堆区建立的还是栈区建立的?不太懂,求高手指教……
     
    另外,最开始用递归实现buildTree函数时,我写成了如下形式:
    void buildTree(TreeNode * newroot, vector<int> &A,int st,int ed)
    {
        if (st>ed)
        {
            return ;
        }
        int mid=(st+ed)/2;
        newroot=new TreeNode(A[mid]);
        buildTree(newroot->left,A,st,mid-1);
        buildTree(newroot->right,A,mid+1,ed);
    }

    /* --------- sortedArrayToBST函数内调用 --------- */

    TreeNode * newroot=NULL;
    builtTree(newroot,A,0,ed);

    
    

    //int ed=A.size()-1;
    //int mid=ed/2;
    //TreeNode *newroot=new TreeNode(A[mid]);//第一个节点;

    //builtTree(newroot->left,A,0,mid-1);
    //builtTree(newroot->right,A,mid+1,ed);

     

    即指针做形参,并且在函数内通过new来给形参赋值。但这样做是没用的,因为地址值传递不到实参那里,所以运行程序直接返回了NULL。在sortedArrayToBST内创建根节点运行后只返回数组中间值。

     
  • 相关阅读:
    Guru's Guide to SQL Server Architecture and Internals
    如何诊断修正17883,17884,17887,17888错误
    Debugging a SQL Server query with WinDbg
    Windbg调试Sql Server 进程
    SQL SERVER 技术博客 外文
    sql server book
    SQL Server Debugging with WinDbg – an Introduction
    Concurrency(Locking, Blocking and Row Versioning)
    如何自学Android, 教大家玩爆Android
    Storage protocol stacks
  • 原文地址:https://www.cnblogs.com/Tang-tangt/p/9180166.html
Copyright © 2011-2022 走看看