问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为N.只包含小写字母
输出格式
如果可能,输出最少的交换次数。
否则输出Impossible
样例输入
5
mamad
样例输出
3
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static void main(String[] args) throws IOException{ BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); int len = Integer.parseInt(reader.readLine()); char[] s = reader.readLine().toCharArray(); reader.close(); if (palindrome(s, 0, len - 1)) { System.out.println(cnt); } else { System.out.println("Impossible"); } } private static int cnt = 0; private static boolean haveMiddle = false; private static boolean palindrome(char[] s, int a, int b) { if (b <= a) { return true; } // 从最后的位置开始遍历字符串 for (int i = b; i > a; i--) { if (s[a] == s[i]) { exchangeTo(s, i, b); cnt += getExchangeTimes(i, b); return palindrome(s, a + 1, b - 1); } } // 如果没有出现过中间字符 if (!haveMiddle) { haveMiddle = true; cnt += getExchangeTimes(a, s.length / 2); return palindrome(s, a + 1, b); } return false; } private static int getExchangeTimes(int a, int b) { return b - a; } private static void exchangeTo(char[] s, int a, int b) { char temp = s[a]; for (int i = a; i < b; i++) { s[i] = s[i + 1]; } s[b] = temp; } }