Here's a simple and efficient solution:
Let Q[ s2[i] ] = the positions character s2[i] is on in s2
. Let P[i] = on what position is the character corresponding to s1[i] in the second string
.
To build Q and P:
for ( int i = 0; i < s1.size(); ++i )
Q[ s2[i] ].push_back(i); // basically, Q is a vector [0 .. 25] of lists
temp[0 .. 25] = {0}
for ( int i = 0; i < s1.size(); ++i )
P[i + 1] = 1 + Q[ s1[i] ][ temp[ s1[i] ]++ ];
Example:
1234
s1: abcd
s2: acdb
Q: Q[a = 0] = {0}, Q[b = 1] = {3}, Q[c = 2] = {1}, Q[d = 3] = {2}
P: P[1] = 1, P[2] = 4 (because the b in s1 is on position 4 in s2), P[3] = 2
P[4] = 3
P
has 2
inversions (4 2
and 4 3
), so this is the answer.
This solution is O(n log n)
because building P
and Q
can be done in O(n)
and merge sort can count inversions in O(n log n)
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…