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

参考的博客: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. 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时3

    课时3 计算机视觉历史回顾与介绍下 ImageNet有5000万张图片,全部都是人工清洗过得,标注了超过2万个分类. CS231n将聚焦于视觉识别问题,图像分类关注的是大图整体:物体检测告诉你东西具体 ...

  2. javascript的回调函数

    函数也是对象 想弄明白回调函数,首先的清楚地明白函数的规则.在javascript中,函数是比较奇怪的,但它确确实实是对象.确切地说,函数是用Function()构造函数创建的Function对象.F ...

  3. “玲珑杯”线上赛 Round #17 河南专场 A: Sin your life(和化积公式)

    传送门 题意 略 分析 首先将sin(x)+sin(y)+sin(z)h转化成\(2*sin(\frac{x+y}2)*cos(\frac{x-y}2)+sin(z)\),而cos(z)=cos(-z ...

  4. poj2385【基础DP】

    挑战DP 题意: 有两棵树,给每分钟有苹果掉落的苹果树,一开始B在 1 树下,B最多只能移动W步,求一个最大数量拿到的. 思路: 一开始想的是,我对于每分钟情况来说无非是等于之前的在本位置+1,或者等 ...

  5. N的阶乘HDOJ1042

    我记得有一份代码是非常有技巧的,然而这一份就是很死板-每次跑50000,因为10000的阶乘最多才50000位,这样肯定就过了 #include<cstdio> #include<s ...

  6. 函数和代码复用 --Python

    1.关于递归函数的描述,以下选项中正确的是 A.包含一个循环结构 B.函数比较复杂 C.函数内部包含对本函数的再次调用 D.函数名称作为返回值 答案:D 答案解析:递归函数是指函数内部包含对本函数的再 ...

  7. SQLite3初级使用

    (1)SQL的指令格式 所有的SQL指令都是以分号(;)结尾的.如果遇到两个减号(--)则代表注解,sqlite3会略过去. (2)建立资料表 假设我们要建一个名叫film的资料表,只要键入以下指令就 ...

  8. 树的直径初探+Luogu P3629 [APIO2010]巡逻【树的直径】By cellur925

    题目传送门 我们先来介绍一个概念:树的直径. 树的直径:树中最远的两个节点间的距离.(树的最长链)树的直径有两种方法,都是$O(N)$. 第一种:两遍bfs/dfs(这里写的是两遍bfs) 从任意一个 ...

  9. Java 反射机制详解(下)

    续:Java 反射机制详解(上) 三.怎么使用反射 想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属 ...

  10. nginx用户统计

    1 概念 PV:页面访问量,即PageView,用户每次对网站的访问均被记录,用户对同一页面的多次访问,访问量累计. UV:独立访问用户数:即UniqueVisitor,访问网站的一台电脑客户端为一个 ...