Orange


私信TA

用户名:uq_30153938431

访问量:8934

签 名:

等  级
排  名 920
经  验 3478
参赛次数 0
文章发表 16
年  龄 23
在职情况 在职
学  校 广西建设职业技术学院
专  业 网络技术

  自我简介:

解题思路:

思路:回文字符串就是 字符从字符串成中间折叠对称的字符串。

*       如:abdba、abcdcba....等等。

* 我们会发现一个规律,每一个字符都是成对存在、除了中间的那一个字符,其他的都是成对存在。

* 因此,我们可以用这个特性判断该字符串是否可以构成回文字符串-->实现方法tally

*      我们确定可以该字符串可以构成回文字符串后,接下来就是对没有形成回文字符串的字符进行移动,以最小的移动步数

* 构成回文字符串,如:mamad它可以构成回文字符串,我们的目标就是把它变成madam。

* 结合回文和观察的规律发现:回文是i位置上的字符等于str.length - i位置上的字符。这样我们可以推理,我们把每一个位置上的字符

* 都以最小的步数构成 str[i] == str[str.length - i]。那总体上来说是不是可以做到最小步数把非回文字符串变成回文字符串了。

* 其实这个方法可以用一些方法来证明它的正确性,我的数学意识太差,不知道用什么方法去证明,如果有大佬可以推导出证明过程,可以留言给我吗?。

* 这个方法的答案是正确的。

* 实现细节:我们以中间为节点。找左边的字符,看看在右边(这个右边相对与中间点左边当前的字符)是否有与其想同的字符,相同就进行移动。

*      例子:mamad,aadmm。

*      对于mamad,我们可以从左边开始找,发现第一个 m和第三个m相等,然后就把第三个m移动到d的位置。一直重复这个动作,

* 最后就可以得到madam了。

*      对于aadmm我们从左边开始找,发现到admma之后,第二个d、在字符串中没有第二个与它相同,所以不可能发生移动。

* 然后就结束了,因为我们在左边找,看右边是否与左边的字符相等,相等就移动。为什么这样子做呢?因为回文字符串就是

* 以中间点进行一个分界线,以这条分界线对称。所以我们可以左右两边找,先找左边,在找右边。

*/

无标题.png

注意事项:

    注意思路,就是每一个字符移动的最小步数,和起来就是总的最小步数

参考代码:

//统计字母出现的次数,判断是否有条件构成回文
	public boolean tally(char[] array) {
		int statistics[] = new int[26];
		for (int i = 0; i < array.length; i++) {
			statistics[array[i] - 'a'] += 1;
		}
		int record = 0;
		for (int i = 0; i < statistics.length; i++) {
			if (statistics[i] % 2 == 1) {
				record += 1;
			}
		}
		if (record > 1) {
			return true;
		}
		return false;
	}
	public String change(String arg) {
		char array[] = arg.toCharArray();
		if (tally(array)) {
			return "Impossible";
		}
		int number = 0;// 移动次数
		for (int i = 0; i < array.length / 2; i++) {
			for (int j = array.length - (i + 1); j > i; j--) {
				//左边找
				if (array[i] == array[j]) {
					// 把寻找到的字符array[j]移动到array.length - (i + 1)这个位置
					for (int j2 = j; j2 < array.length - (i + 1); j2++) {
						char character = array[j2];
						array[j2] = array[j2 + 1];
						array[j2 + 1] = character;
					}
					// 统计次数
					number += array.length - (i + 1) - j;
					break;//找到了最近的就结束
				}
				//右边找
				if (array[array.length - (i + 1)] == array[array.length - (j+1)]) {
					//把寻找到的字符array[array.length - (j+1)] 往 i移动
					for (int j2 = array.length - (j+1); j2 > i; j2--) {
						char a = array[j2];
						array[j2] = array[j2 - 1];
						array[j2 - 1] = a;
					}
					//统计次数
					number += array.length - (j + 1) - i;
					break;//找到了最近的就结束
				}
			}
		}
		return number + "";
	}


 

0.0分

23 人评分

  评论区

膜拜大佬
2024-03-25 23:57:22
你已经可以升本了
2023-03-08 22:34:45
有个小不懂,第27、28行,位置 i 和位置 j 的值相等,所以要把 j 交换到 length - i - 1,但是如果位置 i 和位置 length - i - 1 的值也相等呢,不是就不用交换了吗?
2022-03-15 17:57:00
好解释  牛逼
2022-03-05 17:42:41
不一定要除了中间吧,所有字母都成队,一样可以组成回文
2021-04-26 21:08:14
膜拜大佬
2021-01-18 17:20:07
  • «
  • 1
  • »