总是在看完别人的代码之后,才发现自己的差距!
我的递归:
先把左侧扁平化,再把右侧扁平化。
然后找到左侧最后一个节点,把右侧移动过去。
然后把左侧整体移到右侧,左侧置为空。
很复杂吧!
如果节点很长的话,这个耗时是很大的。O(n^2) ?差不多了!
菜逼啊!时间估计都错了!!!
时间是多少呢?
while 最左侧的数,会不断被遍历!是这样的。大概会被遍历o(n)次
所以还是O(n^2)?
反正是复杂了。
void flatten(struct TreeNode* root) { if(root == NULL) return; flatten(root->left); flatten(root->right); if(root->left) { struct TreeNode *p = root->left; while(p -> right) { p = p->right; } p->right = root->right; root->right = root->left; root->left = NULL; } return root; }
看看人家多么行云流水的操作!代码简洁,效率高!没有重复操作!厉害啊!
struct TreeNode *pre = NULL; void convert(struct TreeNode* root) { if(root == NULL) return; convert(root->right); convert(root->left); root->right = pre; root->left = NULL; pre = root; } void flatten(struct TreeNode *root) { pre = NULL; convert(root); }
什么思路?
先把右侧变成一个链表,记录下表头。
再把左侧变成链表,右侧的表头作为尾部。
右子树变成左子树的最右儿子的右儿子。
巧妙啊。。。
另外,要注意全局变量每次使用前都要重新初始化。所以外面套了一层。