蓝桥杯练习系统之基础训练Java版(2-19)—— 完美的代价
**难度等级:中等**
**关键字:贪心算法**
问题描述:
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回
文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式:
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为N.只包含小写字母
输出格式:
如果可能,输出最少的交换次数。
否则输出Impossible
样例输入:
5
mamad
样例输出:
3
思路探索:
代码如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String str = sc.next();
int oddNum = 0; //用来判断是否只有一个奇数
int count = 0; //交换的次数
int []cnt = new int[26];; //将字符串转换成数组的形式
char[] chars = str.toCharArray();
int len = n - 1;
int flag = 0;
//用数组存储数组元素下标对应的序号字母出现的次数
for(int i = 0; i < str.length(); i++) {
cnt[str.charAt(i)-'a']++;
}
//统计只出现奇数次的字母的个数
for(int i = 0; i < 26; i++) {
if(cnt[i] % 2 == 1)
oddNum++;
}
for (int i = 0; i < len; i++) {
for (int j = len; j >= i; j--) {
if(i == j){ //在chars[i]数组中没有找到相同的字符
/*
* 字符串的长度为偶数,且存在出现次数为奇数个的字符或者存在两个出现次数为奇数个的字符
*/
if((n % 2 == 0 && oddNum >= 1) || (oddNum > 1)) {
System.out.println("Impossible");
return;
}
count += n / 2 - i; //将奇数次的字符交换到中间位置的次数
}
if(chars[i] == chars[j]) { //如果找到了,将chars[j]交换到最后
for(int k = j; k < len; k++) {
char temp = chars[k];
chars[k] = chars[k + 1];
chars[k + 1] = temp;
count++;
}
len--;//末尾递减
break;
}
}
}
System.out.println(count);
}
}
希望能对您有帮助!谢谢。(还有更简单的方法,但是难理解,后续更新…)