题目:将非递减有序的链表转化为平衡二叉查找树!

参考的博客:http://blog.csdn.net/worldwindjp/article/details/39722643

利用递归思想:首先找到链表的中间节点,于是链表被分为了由该中间节点划分开来的两部分。递归地处理这两部分,最终便得到了平衡二叉查找树。

 /**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
if(!head)
return NULL;
if(head->next==NULL){
TreeNode*root=new TreeNode(head->val);
return root;
}
ListNode*pre=getLeftOfMid(head),*mid=pre->next;
TreeNode*root=new TreeNode(mid->val);//根
pre->next=NULL;
root->left=sortedListToBST(head);//左子树
root->right=sortedListToBST(mid->next);//右子树
return root;
}
ListNode* getLeftOfMid(ListNode*head)//说简单点,就是获取链表中间节点,作为树的根节点,并由此划分根的2个子树
{
if(!head)
return NULL;
ListNode*pre=head,*back=head;
while(back!=NULL)//back后退的步数大致是head的两倍,确保pre能落在中间节点位置的前一结点处
{
back=back->next;
if(!back)
break;
back=back->next;
if(!back)
break;
pre=head;
head=head->next;
}
return pre;
}
};

上面的方法是一种自顶向下的方法,先找到root然后对左右子树分别递归调用。

网上又看到一种自底向上的方法,算法复杂度为O(N)。先递归构建左子树,在构建左子树的同时不断移动链表的头指针,链表的头指针永远是对应当前子树位置的。一直到左叶子节点,左叶子节点对应的就是链表的第一个元素,生成左叶子节点之后移动链表当前指针。

看这个博客:http://blog.csdn.net/linhuanmars/article/details/23904937

这里的问题是对于一个链表我们是不能常量时间访问它的中间元素的。这时候就要利用到树的中序遍历了,按照递归中序遍历的顺序对链表结点一个个进行访问,而我们要构造的二分查找树正是按照链表的顺序来的。思路就是先对左子树进行递归,然后将当前结点作为根,迭代到下一个链表结点,最后在递归求出右子树即可。整体过程就是一次中序遍历,时间复杂度是O(n),空间复杂度是栈空间O(logn)。

来看一下对应数组的中序遍历建立BST代码:

 /**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
int cur;//不去掉这前面的static编译不会通过的
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
cur = ;
if (nums.size() == )
return NULL;
return helper(nums, , nums.size() - );
}
TreeNode* helper(vector<int>&nums, int l, int r)
{
if (l > r)
return NULL;
int mid = (l+r) / ;
TreeNode*left=helper(nums, l, mid-);
TreeNode * root = new TreeNode(nums[cur++]);//回忆考研时候,中序遍历中,这个地方才是真正干活的语句(并且终须遍历二叉排序树得到的就是有序数组)
root->left = left;
root->right = helper(nums, mid + , r);
return root;
}
};

Convert Sorted List to Balanced Binary Search Tree leetcode的更多相关文章

  1. Convert Sorted List to Balanced Binary Search Tree (BST)

    (http://leetcode.com/2010/11/convert-sorted-list-to-balanced-binary.html) Given a singly linked list ...

  2. Convert Sorted Array to Balanced Binary Search Tree (BST)

    (http://leetcode.com/2010/11/convert-sorted-array-into-balanced.html) Given an array where elements ...

  3. Convert Sorted Array to Binary Search Tree leetcode java

    题目: Given an array where elements are sorted in ascending order, convert it to a height balanced BST ...

  4. Validate Binary Search Tree [LeetCode]

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  5. Recover Binary Search Tree [LeetCode]

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  6. Validate Binary Search Tree——LeetCode

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  7. Recover Binary Search Tree leetcode java

    题目: Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without chan ...

  8. Validate Binary Search Tree leetcode java

    题目: Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is define ...

  9. Lowest Common Ancestor of a Binary Search Tree -- LeetCode

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

随机推荐

  1. codeforces 724C

    在一个nxm的镜面二维空间内,向(1,1)发射一条射线,来回反射,当遇到四个角之一时光线消失. 给K个点,问K个点第一次被射中是什么时候(v = sqrt(2)) 解:注意到只有 2*(n+m)个对角 ...

  2. ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 01. 创建项目 +项目结构和配置简介

    新建项目:Tutotial.Web 解决方案名称可以把web去掉 视频里面把git这个选项勾选了.我就不勾选了 dotnet CLI创建项目 首先必须安装好了.net Core的SDK dotnet ...

  3. 任务30:RoutingMiddleware介绍以及MVC引入

    任务30:RoutingMiddleware介绍以及MVC引入 前面讲到app.Map的方式,它也可以实现路由 当我们的url是task的时候,就会执行里面的context的输出内容 app.Map( ...

  4. 【WIP】iOS Xcode基础

    创建: 2018/04/18 Xcode基本操作  创建项目处的填空  Product Name 应用名 英语字母  Organization Name 公司/组织/个人名 英语字母  Organiz ...

  5. 利用thrift在c++、java和python之间相互调用

    转自:http://blog.csdn.net/andy_yf/article/details/7487384 thrift做为跨语言调用的方案有高效,支持语言较多,成熟等优点:代码侵入较强是其弱点. ...

  6. bzoj 3697: 采药人的路径【点分治】

    点分治,设当前处理的块的重心为rt,预处理出每个子树中f[v][0/1]表示组合出.没组合出一对值v的链数(从当前儿子出发的链),能组合出一对v值就是可以有一个休息点 然后对于rt,经过rt且合法的路 ...

  7. 洛谷P3577 [POI2014]TUR-Tourism

    给定一个n个点,m条边的无向图,其中你在第i个点建立旅游站点的费用为Ci.在这张图中,任意两点间不存在节点数超过10的简单路径.请找到一种费用最小的建立旅游站点的方案,使得每个点要么建立了旅游站点,要 ...

  8. ES6之箭头函数深入理解

    相对于普通函数的区别 新的书写方式 this 的改变 不能当构造函数 没有 prototype 属性 没有 arguments 对象 新的书写方式 书写方式很简单!直接看下图, 常规方式写一个函数 c ...

  9. 单表:1.查询全部 2.条件查询 JSP Servlet

  10. Hexo瞎折腾系列(6) - 将博客同时部署到Github和Coding

    前言 由于本人只是将Hexo博客同时部署到 Github 和 Coding.net ,所以这里只介绍怎么同时部署到这两个网站的pages. 之所以选择这两个网站,是因为国外用户可以访问 Github, ...