One way to think about this problem is to use the fact that the camp tree in order will produce all the elements in sorted order. If you find deviations from the ordered order during this walk, you can try to find two elements that are in the wrong place.
See how to do this for a simple sorted array, then use our algorithm to create something that works on trees. Intuitively, if we start with a sorted array and then replace two (not equal!) Elements, we get a number of elements in the array that will be inappropriate. For example, given an array
1 2 3 4 5
If we replace 2 and 4, we get this array:
1 4 3 2 5
How would we find that 2 and 4 were replaced here? Well, since 4 is the larger of the two elements and has been resized down, it should be larger than both elements around it. Similarly, since 2 has been replaced, it must be smaller than both elements around it. From this we can conclude that 2 and 4 were replaced.
However, this does not always work correctly. For example, suppose we exchange 1 and 4:
4 2 3 1 5
Here, both 2 and 1 are smaller than their neighboring elements, and both 4 and 3 are larger than them. From this it can be said that two of these four somehow changed places, but it is not clear which of them should be changed. However, if we take the largest and smallest of these values ββ(1 and 4, respectively), we get the pairs that have been replaced.
More generally, to find items that have been replaced in sequence, you want to find
- The largest local maximum in the array.
- The smallest local minimum in the array.
These two elements are inappropriate and should be replaced.
Now think about how to apply this to trees. Since moving in order in the tree will result in sorting the sequence with two elements out of order, one option would be to walk in the tree, recording the sequence of order of the elements found, and then using the above algorithm. For example, consider your original BST:
20 / \ 15 30 / \ / \ 10 17 25 33 / | / \ / \ | \ 9 16 12 18 22 26 31 34
If we linearize it into an array, we get
9 10 16 15 12 17 18 20 22 25 26 30 31 33 34
Notice that 16 is larger than its surrounding elements, and 12 is smaller than it. This immediately tells us that 12 and 16 were replaced.
Thus, a simple algorithm to solve this problem would be to make the tree move in a linear fashion to linearize it into a sequence like a vector or deque , then scan this sequence to find the largest local maximum and the smallest local minimum. This will work in O (n) time using O (n) space. A more complex but more compact algorithm is to track only three nodes at a time - the current node, its predecessor and its successor, which reduces memory usage to O (1).
Hope this helps!