0

I would like to solve this problem from TopCoder, in which a String is given and in each step you have to replace all occurrences of an character (of your choice) with another character (of your choice), so that at the end after all steps you get a palindrome. The problem is to identify the minimum total number of replacements.

Ideas so far: I can identify that the string after every step is simply a node/vertex in a graph and that the cost of every edge is the number of replacements made in the step, but I don't see how to use greedy for that (it is definitely not the Minimum Spanning Tree problem). I don't think it makes sense to identify all possible nodes & edge costs and to convert the problem in the Shortest Path problem. On the other side, I think in every step it makes sense to replace the character X with the biggest number of conflicts, with the character Y in conflict with X that occurs most in the string.

Anyway, I can't either prove that it works. Also I can't identify any known problems in this. Any ideas?

V G
  • 18,822
  • 6
  • 51
  • 89
  • Well, have you built a naive solution where you search all combinations? It shouldn't grow too big for short words (since you'll terminate once you only have one letter left). Actually, I think you can get an acceptable fast solution if you just do a search starting from the minimum (since you'll always be bound by the min which is much smaller than the theoretical max). – CookieOfFortune Sep 23 '13 at 21:01
  • 1
    Topcoder post solutions to their problems. The editorial for this problem is at http://apps.topcoder.com/wiki/display/tc/SRM+589#GooseTattarrattatDiv1 – Peter de Rivaz Sep 23 '13 at 21:07
  • @CookieOfFortune I haven't, but I think there are many possibilities. to start from which minimum? You get to properties for every char: the number of conflicts and the number of occurrences. – V G Sep 23 '13 at 21:12
  • @PeterdeRivaz Do you know how I get the solution for a random problem there? – V G Sep 23 '13 at 21:12
  • @AndreiI I guess I mean minimum as in the character that appears the least in that word. Start from there and once a palindrome is found, set the changes for that value as a threshold. I think it could work although worst case is pretty bad. – CookieOfFortune Sep 23 '13 at 21:14
  • @CookieOfFortune I think there are at least n! possibilities (when n is the number of characters with conflicts), because you have to consider the order in which you make the replacements. – V G Sep 23 '13 at 21:22
  • @AndreiI Well, Klas has the right answer I believe... – CookieOfFortune Sep 23 '13 at 21:29

1 Answers1

0

You need to identify disjunct sets of characters. A disjunct set of characters is a set of characters that will all have to become the same character in order for the string to become a palindrome.

Example:

Let's say we have the string abcdefgfmdebac

It has 3 disjunct sets, abc, de and fgm

Algorithm:

  1. Pick the first character and check all occurences of it picking up other characters in the set. In the example string we start with a and pick up band c (because they sit on the opposite sides of the two ain our string). We repeat the process for band c, but no new characters are added to the set. So abc is our first disjunct set. Continue doing this with the remaining characters.

  2. A disjunct set of n characters (counting all characters) needs n-m replacements, where m is the number of occurences of the most frequent character. So simply sum over the sets.

In our example it takes 4 + 2 + 2 = 8 replacements.

Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
  • Again I didn't see the Union-Find problem! But I think the number of replacements is not so easy: for example in the abc connected component/disjunct you have to replace a with say c (a occures 2 times), and then say b (2 occurrences) with again c (but after every replacement the letters change). – V G Sep 23 '13 at 21:34
  • The sets are disjunct - meaning the characters in each set occur in that set only. Replacements in one set do not affect any other set. – Klas Lindbäck Sep 23 '13 at 21:41
  • Yes, that is clear. I said only the the total number of replacements in the first disjoint set is not 2, but can vary depending on the order in which you replace. Because notice that, when you replace a, you replace all occurrences of a in the whole String (i.e 2). And then, when you replace b, you get again 2 replacements, with a total of 4 replacements to solve the first disjoint set. So this sub-problem is to be solved with greedy I think. – V G Sep 23 '13 at 21:46
  • Ah, I didn't read the problem, only your re-cap of it. In that case you need to convert all characters in a set to the most numerous character in that set. I'll amend my answer. – Klas Lindbäck Sep 23 '13 at 21:50