1. 问题描述
2. 解法一:递归
算法思想
(1)使用一个指针preNode指向当前结点root的前继。(例如root为指向10的时候,preNode指向8)
(2)对于当前结点root,有root->left要指向前继preNode(中序遍历时,对于当前结点root,其左孩子已经遍历完成了,此时root->left可以被修改。);同时,preNode->right要指向当前结点(当前结点是preNode的后继),此时对于preNode结点,它已经完全加入双向链表。
代码
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode* preNode;//preNode一定是全局变量。
TreeNode* Convert(TreeNode* pRootOfTree) {
if (!pRootOfTree) return pRootOfTree;
TreeNode* p = pRootOfTree;
while (p->left) p = p->left;//找到双向链表的开头。
inorder(pRootOfTree);
return p;
}
void inorder(TreeNode* root){
if (!root) return;
inorder(root->left);
root->left = preNode; //当前结点中需要进校的调整。
if (preNode) preNode->right = root;
preNode = root;//更新preNode,指向当前结点,作为下一个结点的前继。
inorder(root->right);
}
};
时间空间复杂度分析
时间复杂度:O(N),等于中序遍历的时间复杂度。
空间复杂度:O(N)。没有申请新的空间,但是递归调用栈占用了N的空间。