时间复杂度O(n)
- class Solution {
- public:
- int makeVine(TreeNode* grand, int cnt = 0)
- {
- auto n = grand->right;
- while (n != nullptr)
- {
- if(n->left != nullptr)
- {
- auto old_n = n;
- n = n->left;
- old_n->left = n->right;
- n->right = old_n;
- grand->right = n;
- }
- else{
- cnt++;
- grand = n;
- n = n->right;
- }
- }
- return cnt;
-
- }
- void compress(TreeNode *grand, int m) {
- auto n = grand->right;
- while (m-- > 0)
- {
- auto old_n = n;
- n = n->right;
- grand->right = n;
- old_n->right = n->left;
- n->left = old_n;
- grand = n;
- n = n->right;
- }
-
- }
- TreeNode* balanceBST(TreeNode *root) {
- TreeNode grand;
- grand.right = root;
- auto cnt = makeVine(&grand);
- int m = pow(2, int(log2(cnt + 1))) - 1;
- compress(&grand, cnt - m);
- for (m = m / 2; m > 0; m /= 2)
- compress(&grand, m);
- return grand.right;
- }
- };
1. 将最初的树转变为藤蔓。 通过进行右旋转,我们将树展平为“链表”,其中头是以前最左边的节点,尾部是以前最右边的节点。
2. 将树转换为藤蔓后,计算 节点总数(cnt)。
3. 计算最接近的完美平衡树的高度:h = log2(cnt + 1)。
4. 计算最接近的完美平衡树中的节点数:m = pow(2, h) - 1。
5. 向左旋转 cnt - m 个节点以掩盖多余的节点。
6. 左旋转 m/2 个节点。
7. 将 m 除以 2,并在 m / 2 大于零时重复上述步骤。