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

参考的博客: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. Binder通信机制介绍

    1.Binder通信机制介绍 这篇文章会先对比Binder机制与Linux的通信机制的差别,了解为什么Android会另起炉灶,采用Binder.接着,会根据 Binder的机制,去理解什么是Serv ...

  2. VC链接hid.lib出错问题解决方案

    写一个HID的客户端小程序,调用了一些HID API,但是链接时出现了奇怪的现象. 尽管我已经把头文件和lib文件加入到了VC的Include和Lib目录中,但不管我用VC链接,还是在DDK环境下链接 ...

  3. 036--MySQL扩展

    一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. SELECT * FROM ( S ...

  4. 任务43:Identity MVC:UI

    基于原来做的cookie认证的代码:MvcCookieAuthSample 增加登陆和退出的方法: 增加Login和SignIn这两个Action方法. 在Views下面创建Account文件夹,然后 ...

  5. 基于事件驱动机制,在Service Mesh中进行消息传递的探讨

    翻译 | 宋松 原文 | https://www.infoq.com/articles/service-mesh-event-driven-messaging 关键点 当前流行的Service Mes ...

  6. 了解Hypertable

    1.为什么要了解Hypertable, 因为全球最大的搜索引擎公司百度使用了Hypertable(http://www.baidu.com/s?wd=Hypertable),Hypertable类似于 ...

  7. poj 2960 S-Nim【SG函数】

    预处理出SG函数,然后像普通nim一样做即可 #include<iostream> #include<cstdio> using namespace std; const in ...

  8. 用CSS绘制三角形

    其实用HTML CSS绘制三角行 是非常简单的 ,我在网上看了不少人写的博客,里面写的好复杂样子,反正我是看的云里雾里的,说实话是挺简单的. 首先提出一段代码: <!DOCTYPE html&g ...

  9. 在Android 源码中添加系统服务

    Android系统本身提供了很多系统服务,如WindowManagerService,PowerManagerService等.下面描述一下添加一个系统服务的具体步骤. 1.定义自定义系统服务接口 撰 ...

  10. 492 Construct the Rectangle 构建矩形

    详见:https://leetcode.com/problems/construct-the-rectangle/description/ C++: class Solution { public: ...