题目
题目同上一篇文章,即题目将二叉树按照中序顺序转换成双向链表
思路
方法二:利用递归函数,不使用任何容器。时间复杂度为O(N),额外空间复杂度为O(h),h为二d d d df叉树的高度
- 首先需要一个新的类,来返回有序双向链表的头节点和尾节点,ReturnTpye类
- 先将以X为头节点的左子树转换为有序双向链表,再将X的右子树转换为有序双向链表,通过X把两部分连接即可
- 具体实现看下面的代码部分
源码
public class ReturnType{
public Node start;
public Node end;
public ReturnType(Node start, Node end){
this.start=start;
this.end=end;
}
}
public Node convert2(Node head){
if(head==null){
return null;
}
return process(head).start;
}
public ReturnType process(Node head){
if(head==null){
return new ReturnType(null,null);
}
ReturnType leftList=process(head.left);
ReturnType rightList=process(head.right);
if(leftList.end!=null){
leftList.end.right=head;
}
head.left=leftList.end;
head.right=rightList.start;
if(rightList.start!=null){
rightList.start.left=head;
}
return new ReturnType(leftList.start!=null?leftList.start:head,
rightList.end!=null?rightList.end:head);
}
解析
时间复杂度可以用process递归函数发生的次数来估算,process会处理所有子树,子树的数量就是二叉树节点的数量。所以时间复杂度为O(N),process递归函数最多会占用二叉树高度为h的栈空间,额外的空间复杂度也就是O(h)了。
扩展
本题在复杂度方面完全取决于二叉树的遍历的实现。有没有时间复杂度为O(N),额外空间复杂度为O(1)的遍历实现呢?也就是既不用栈,也不用递归函数,只用几个变量?有的,后续在二叉树的部分,还会结合神级的遍历方法('遍历二叉树的神级方法')重新实现这一道题。