java完美回文串的代价_蓝桥杯基础练习 完美的代价(JAVA)

问题描述

回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。   交换的定义是:交换两个相邻的字符   例如mamad   第一次交换 ad : mamda   第二次交换 md : madma   第三次交换 ma : madam (回文!完美!) 输入格式   第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)   第二行是一个字符串,长度为N.只包含小写字母 输出格式   如果可能,输出最少的交换次数。   否则输出Impossible 样例输入 5 mamad 样例输出 3

算法思路

由问题描述可以得知,有两种情况会输出“Impossible”,一种是当字符串长度为奇数且出现两个及两个以上出现次数为奇数个的字符,另一种是字符串长度为偶数但存在出现次数为奇数个的字符。当字符串具备构成一个完美的回文串条件时,我们可以从最左边的元素开始查找,然后从右向左查找能够和最左边元素匹配的字符,若匹配成功则将该字符交换至字符串的最右边,然后将从右边查找的标记下标减一并从紧邻最左边的第二个字符开始再次查找,依次类推直至两个索引标记相等。

算法实现

import java.util.Scanner;

public class Main{

public static void main(String[] args) {

Scanner input = new Scanner(System.in);

int num = input.nextInt();

String s = input.next();

int oldNum = 0;//判断是否已经存在一个单独的奇数个数的字符了

int cnt = 0;//总共交换次数

int end = num - 1;//字符串最后一个字符的下标

char[] chars = s.toCharArray();

for (int i = 0; i < end; i++) {

for (int j = end; j >= i; j--) {

if(i == j){//chars[i]未找到与之相等的字符

if(num % 2==0 || oldNum == 1){//字符串长度为偶数个且存在出现次数为奇数个的字符或者存在两个出现次数为奇数个的字符

System.out.println("Impossible");

return;

}

oldNum = 1;//字符串长度为奇数且找到一个字符出现的次数为奇数

cnt += num / 2 - i;//将奇次字符交换到中间位置的次数

}

if(chars[i]==chars[j]){//如果找到了,将chars[j]交换到最后

for (int k = j; k < end; k++) {

char t = chars[k];

chars[k] = chars[k + 1];

chars[k + 1] = t;

cnt++;

}

end--;//末尾递减

break;

}

}

}

System.out.println(cnt);

}

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值