#剑指offer26二叉搜索树与双向链表
二叉搜索树与双向链表
https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&&tqId=11179&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
剑指offer26二叉搜索树与双向链表
剑指offer26
1、常规思路--保存到有序数组在更改
中序遍历保存到数组,然后再更改指向
时间复杂度:O(n), 空间复杂度:O(n)
缺点:多次(两次)遍历
class Solution { public: vector<TreeNode*>v; void midTraverse(TreeNode*pRoot) { if(!pRoot) return; midTraverse(pRoot->left); v.push_back(pRoot); midTraverse(pRoot->right); } TreeNode* Convert(TreeNode* pRootOfTree) { if(!pRootOfTree) return nullptr; midTraverse(pRootOfTree); for(int i=0;i<v.size()-1;i++) { v[i]->right=v[i+1]; v[i+1]->left=v[i]; } v[0]->left=nullptr; v[v.size()-1]->right=nullptr; return v[0]; } };
2、优化,一次遍历
全局保存每次遍历的上一个节点,注意细节头尾节点处理
时间复杂度:O(n) 空间复杂度:O(n)
优点:一次遍历
[2]:https://www.nowcoder.com/profile/396966893/codeBookDetail?submissionId=110301954
[个人代码][2]
class Solution { public: TreeNode* lastNode=nullptr;//保存当前遍历的上一个节点,也会保存最后一个节点(未处理) TreeNode* pHead=nullptr; void midTraverse(TreeNode*pRoot) { if(!pRoot) return; midTraverse(pRoot->left); if(lastNode) lastNode->right=pRoot; //上一个节点right指向当前节点 else pHead=pRoot; //链表头,第一次节点的上一个节点为空 pRoot->left=lastNode; //当前节点的left指向上一个节点 lastNode = pRoot; midTraverse(pRoot->right); } TreeNode* Convert(TreeNode* pRootOfTree) { if(!pRootOfTree) return nullptr; midTraverse(pRootOfTree); lastNode->right=nullptr; //处理最后一个节点right指向空 return pHead; } };