109. Convert Sorted List to Binary Search Tree
2016-06-10 10:28
309 查看
题目:
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
题意:
给定一个按升序排列的单链表,将其转换为高度平衡的二叉搜索树。
思路一:
将有序链表存在一个数组里。根据每次访问中间节点当做根节点,递归调用左右子树节点。
代码:30ms
/**
* 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;
vector<int> tmp;
while(head){ //将链表转换为数组
tmp.push_back(head->val);
head = head->next;
}
return sortedArrayTree(tmp, 0, tmp.size()-1);
}
TreeNode *sortedArrayTree(vector<int> &arr, int start, int end){
if(start > end) return NULL;
TreeNode *root = new TreeNode(arr[(start+end)/2]); //取数组中间元素作为根节点
root->left = sortedArrayTree(arr, start, (start+end)/2-1);
root->right = sortedArrayTree(arr, (start+end)/2+1, end);
return root;
}
};
思路二:
定义两个分别为一快一慢的节点变量,慢节点每次向前一步,快节点每次向前两步,当快节点到达末尾时,慢节点到链表中间位置,慢节点值即为二叉搜索树的根节点值,之后依次递归左右子树。
代码:1ms
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode sortedListToBST(ListNode head) {
return rec(head, null);
}
public TreeNode rec(ListNode start, ListNode end){
if(start==end) return null;
ListNode p = start, q = start;
while(q!=end && q.next!=end){ //找到链表中间值
p = p.next;
q = q.next.next;
}
TreeNode root = new TreeNode(p.val); //链表中间值作为根节点
root.left = rec(start, p);
root.right = rec(p.next, end);
return root;
}
}
思路三:
先求出链表长度,将链表长度作为参数传递进递归函数,每次寻找链表中点时,只需要新定义的指针向前移动一般链表长度即可,将找到的节点值作为根源上节点值,之后递归调用左右子树。
代码:28ms
/**
* 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) {
int n = 0;
ListNode *p = head;
while(p!=NULL){ //得到链表长度
n++;
p = p->next;
}
return sortedListToBST(head, n);
}
TreeNode *sortedListToBST(ListNode *head, int n){
if(head==NULL || n==0) return NULL;
ListNode *p = head;
for(int i=1; i<(n+1)/2; ++i){ //每次找到传入长度的中间值
p = p->next;
}
TreeNode *root = new TreeNode(p->val); //将中间值作为根节点
root->left = sortedListToBST(head, (n+1)/2-1);
root->right = sortedListToBST(p->next, n-(n+1)/2);
return root;
}
};
思路四:
以上三种方法都是自顶向下生成的二叉树,本方法采用自底向上的方式生成二叉树,迭代递归时,根据链表顺序依次将链表值填入二叉搜索树中。
代码:1ms
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
static ListNode currentHead = null;
public TreeNode sortedListToBST(ListNode head) {
if(head==null) return null;
currentHead = head;
int len = 0;
while(head!=null){ //获取链表长度
len++;
head = head.next;
}
return sortedListToBST(0, len-1);
}
public TreeNode sortedListToBST(int start, int end){
if(start>end) return null;
int mid = start + (end-start)/2;
TreeNode left = sortedListToBST(start, mid-1); //生成左子树
TreeNode root = new TreeNode(currentHead.val);
root.left = left;
currentHead = currentHead.next; //链表后移
root.right = sortedListToBST(mid+1, end); //生成右子树
return root;
}
}
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
题意:
给定一个按升序排列的单链表,将其转换为高度平衡的二叉搜索树。
思路一:
将有序链表存在一个数组里。根据每次访问中间节点当做根节点,递归调用左右子树节点。
代码:30ms
/**
* 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;
vector<int> tmp;
while(head){ //将链表转换为数组
tmp.push_back(head->val);
head = head->next;
}
return sortedArrayTree(tmp, 0, tmp.size()-1);
}
TreeNode *sortedArrayTree(vector<int> &arr, int start, int end){
if(start > end) return NULL;
TreeNode *root = new TreeNode(arr[(start+end)/2]); //取数组中间元素作为根节点
root->left = sortedArrayTree(arr, start, (start+end)/2-1);
root->right = sortedArrayTree(arr, (start+end)/2+1, end);
return root;
}
};
思路二:
定义两个分别为一快一慢的节点变量,慢节点每次向前一步,快节点每次向前两步,当快节点到达末尾时,慢节点到链表中间位置,慢节点值即为二叉搜索树的根节点值,之后依次递归左右子树。
代码:1ms
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode sortedListToBST(ListNode head) {
return rec(head, null);
}
public TreeNode rec(ListNode start, ListNode end){
if(start==end) return null;
ListNode p = start, q = start;
while(q!=end && q.next!=end){ //找到链表中间值
p = p.next;
q = q.next.next;
}
TreeNode root = new TreeNode(p.val); //链表中间值作为根节点
root.left = rec(start, p);
root.right = rec(p.next, end);
return root;
}
}
思路三:
先求出链表长度,将链表长度作为参数传递进递归函数,每次寻找链表中点时,只需要新定义的指针向前移动一般链表长度即可,将找到的节点值作为根源上节点值,之后递归调用左右子树。
代码:28ms
/**
* 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) {
int n = 0;
ListNode *p = head;
while(p!=NULL){ //得到链表长度
n++;
p = p->next;
}
return sortedListToBST(head, n);
}
TreeNode *sortedListToBST(ListNode *head, int n){
if(head==NULL || n==0) return NULL;
ListNode *p = head;
for(int i=1; i<(n+1)/2; ++i){ //每次找到传入长度的中间值
p = p->next;
}
TreeNode *root = new TreeNode(p->val); //将中间值作为根节点
root->left = sortedListToBST(head, (n+1)/2-1);
root->right = sortedListToBST(p->next, n-(n+1)/2);
return root;
}
};
思路四:
以上三种方法都是自顶向下生成的二叉树,本方法采用自底向上的方式生成二叉树,迭代递归时,根据链表顺序依次将链表值填入二叉搜索树中。
代码:1ms
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
static ListNode currentHead = null;
public TreeNode sortedListToBST(ListNode head) {
if(head==null) return null;
currentHead = head;
int len = 0;
while(head!=null){ //获取链表长度
len++;
head = head.next;
}
return sortedListToBST(0, len-1);
}
public TreeNode sortedListToBST(int start, int end){
if(start>end) return null;
int mid = start + (end-start)/2;
TreeNode left = sortedListToBST(start, mid-1); //生成左子树
TreeNode root = new TreeNode(currentHead.val);
root.left = left;
currentHead = currentHead.next; //链表后移
root.right = sortedListToBST(mid+1, end); //生成右子树
return root;
}
}
相关文章推荐
- ecshop静态、 ecshop伪静态、ecshop伪静态设置详细方法、ECSHOP静态化方法
- 每天一命令(4) rmdir (remove empty directories) 1分钟
- ECSHOP系统,数据库表名称、结构
- 图像特征提取之(一)HOG特征
- Web开发之初体验
- 在ECSHOP模板商品列表页 显示商品的评论等级和评论数量
- python学习之路-5 基础进阶篇
- 剑指offer(五十)之序列化二叉树
- Codeforces Round #356 (Div. 2) E. Bear and Square Grid 滑块
- 用路由系统生成输出URL 在视图中生成输出URL 高级路由特性 精通ASP-NET-MVC-5-弗瑞曼
- ECSHOP 2.7.2 文件结构及各文件相应功能介绍
- tomcat 安装时出现 Failed to install Tomcat9 service
- C++第一次上机实验-1
- Maven学习(一)——Maven入门
- ECSHOP设置,只有登录用户才能查看商品详情和商品价格
- Ubuntu下搭建LAMP环境
- Redis分区实现原理
- Ecshop截取变量中的字符长度
- C语言文件
- fragment 1