I haven't worked this out completely, but I think the general idea might help for integers at least. At the cost of more memory, you can maintain a separate data-structure that maintains the ending index of a run of repeated values (since you want to swap your incremented value with the ending index of the repeated value). This is because it's with repeated values that you run into the worst case O(n) runtime: let's say you have [0, 0, 0, 0] and you increment the value at location 0 . Then it is O(n) to find out the last location ( 3 ).

But let's say that you maintain the data-structure I mentioned (a map would works because it has O(1) lookup). In that case you would have something like this:

0 -> 3

So you have a run of 0 values that end at location 3 . When you increment a value, let's say at location i , you check to see if the new value is greater than the value at i + 1 . If it is not, you are fine. But if it is, you look to see if there is an entry for this value in the secondary data-structure. If there isn't, you can simply swap. If there is an entry, you look up the ending-index and then swap with the value at that location. You then make any changes you need to the secondary data-structure to reflect the new state of the array.

A more thorough example:

[0, 2, 3, 3, 3, 4, 4, 5, 5, 5, 7]

The secondary data-structure is:

3 -> 4 4 -> 6 5 -> 9

Let's say you increment the value at location 2 . So you have incremented 3 , to 4 . The array now looks like this:

[0, 2, 4, 3, 3, 4, 4, 5, 5, 5, 7]

You look at the next element, which is 3 . You then look up the entry for that element in the secondary data-structure. The entry is 4 , which means that there is a run of 3 's that end at 4 . This means that you can swap the value from the current location with the value at index 4 :

[0, 2, 3, 3, 4, 4, 4, 5, 5, 5, 7]

Now you will also need to update the secondary data-structure. Specifically, there the run of 3 's ends one index early, so you need to decrement that value:

3 -> 3 4 -> 6 5 -> 9

Another check you will need to do is to see if the value is repeated anymore. You can check that by looking at the i - 1 th and the i + 1 th locations to see if they are the same as the value in question. If neither are equal, then you can remove the entry for this value from the map.

Again, this is just a general idea. I will have to code it out to see if it works out the way I thought about it.

Please feel free to poke holes.

UPDATE

I have an implementation of this algorithm here in JavaScript. I used JavaScript just so I could do it quickly. Also, because I coded it up pretty quickly it can probably be cleaned up. I do have comments though. I'm not doing anything esoteric either, so this should be easily portable to C++.

There are essentially two parts to the algorithm: the incrementing and swapping (if necessary), and book-keeping done on the map that keeps track of our ending indices for runs of repeated values.

The code contains a testing harness that starts with an array of zeroes and increments random locations. At the end of every iteration, there is a test to ensure that the array is sorted.