We can use **Rope** (data structure) to solve this problem, basically we have to build a binary tree and do an in-order traversal in the end to get the final result. If the binary tree is balanced, time complexity will be `O(nlog(n))`

, worst case will be `O(n^2)`

for linear tree.

Before we call reconstructLine function, make sure the input line is sorted by first descending the height then ascending the count, for example:

`[{7, 0}, {7, 1}, {6, 1}, {5, 0}, {5, 2}, {4, 4}]`

The insert logic is like so: the initial weight of each person is the count, compare to each node in the tree, if the weight is less than the node's weight, node's weight + 1, insert the person to the node's left; If the weight is larger than or equal to the node's weight, decrease the person's weight by node's weight, then insert to node's right. When the person is inserted as a leaf, set its weight to 1.

Finally perform an in-order traversal to get the result.

The following code focus on the logic of building the binary tree, sorting the input data should be fairly straightforward, time complexity should be `O(nlog(n))`

```
public static class Solution {
class TreeNode {
int height;
int count;
int weight;
TreeNode left;
TreeNode right;
TreeNode(int h, int c) {
height = h;
count = c;
weight = 1;
}
}
List<int[]> reconstructLine(List<int[]> line) {
// step 1. insert the person to the tree
TreeNode root = null;
for (int[] person : line) {
root = insert(root, person, person[1]);
}
// step 2. do in-order traversal
List<int[]> res = new ArrayList<>();
inorder(root, res);
return res;
}
TreeNode insert(TreeNode root, int[] person, int w) {
if (root == null) {
return new TreeNode(person[0], person[1]);
}
if (person[1] < root.weight) {
// person's count less than current node's weight
// increase current node's weight and insert to the left
root.weight++;
root.left = insert(root.left, person, w);
} else {
// otherwise insert to the right
// and decrease the weight by root.weight
root.right = insert(root.right, person, w - root.weight);
}
return root;
}
void inorder(TreeNode root, List<int[]> res) {
if (root == null) {
return;
}
inorder(root.left, res);
res.add(new int[]{root.height, root.count});
inorder(root.right, res);
}
}
```