package live.every.day.ProgrammingDesign.CodingInterviewGuide.String;
/**
* 添加最少字符使字符串整体都是回文字符串
*
* 【题目】
* 给定一个字符串str,如果可以在str的任意位置添加字符,请返回在添加字符最少的情况下,让str整体都是回文字符串的一种结果。
*
* 【进阶题目】
* 给定一个字符串str,再给定str的最长回文子序列字符串strlps,请返回在添加字符最少的情况下,让str整体都是回文字符串的一
* 种结果。进阶问题比原问题多了一个参数,请做到时问复杂度比原问题的实现低。
*
* 【难度】
* 困难
*
* 【解答】
* 进阶问题。
*
* 如果有最长回文子序列字符串strlps,那么求解的时间复杂度可以加速到O(N)。如果str的长度为N,strlps的长度为M,则整体回
* 文串的长度应该是2xN-M。本文提供的解法类似"剥洋葱"的过程,给出示例来具体说明:
*
* str="A1BC22DE1F",strlps="1221"。res=...长度为2xN-M...
* 洋葱的第0层由strlps[O]和strlps[M-1]组成,即”1...1”。从str最左侧开始找字符'1',发现'A'是str第0个字符,'1'是
* str第1个字符,所以左侧第0层洋葱图外的部分为"A",记为leftPart。从str最右侧开始找字符'1',发现右侧第0层洋葱圈外的部
* 分为"F",记为rightPart。把(leftPart+rightPart的逆序)复制到res左侧未设值的部分,把(rightPart+leftPart逆序)
* 复制到res的右侧未设值的部分,即result变为"AF..FA"。把洋葱的第0层复制进res的左石两侧未设值的部分,即result变为
* "AF1..1FA"。至此,洋葱第0层被剥掉。洋葱的第1层由strlps[1]和strlps[M-2]组成,即”2...2”。从str左侧的洋葱第0层往
* 右找"2",发现左侧第1层洋葱圈外的部分为"BC",记为leftPart。从str右侧的洋葱第0层往左找"2",发现右侧第1层洋葱圈外的
* 部分为"DE",记为rightPart。把(leftPart+rightPart的逆序)复制到res左侧未设值的部分,把(rightPart+lefPart逆序)
* 复制到res的右侧未设值的部分,res变为"AF1BCED..DECB1FA"。把洋葱的第1层复制进res的左右两侧未设值的部分,即result
* 变为"AF1BCED2..2DECB1FA"。第1层被剥掉,洋葱剥完了,返回"AF1BCED22DECB1FA"。
*
* 整个过程就是不断找到洋葱圈的左部分和右部分,把(lefPart+rightPart的逆序)复制到res左侧未设值的部分,把
* (rightPart+leftPart逆序)复制到res的右侧未设值的部分,洋葱剥完则过程结束。具体请参看如下的getPalindrome2方法。
*
* @author Created by LiveEveryDay
*/
public class AddMinCharsMakePalindrome2 {
public static String getPalindrome2(String str, String strlps) {
if (str == null || str.equals("")) {
return "";
}
char[] chas = str.toCharArray();
char[] lps = strlps.toCharArray();
char[] res = new char[2 * chas.length - lps.length];
int chasLeft = 0;
int chasRight = chas.length - 1;
int lpsLeft = 0;
int lpsRight = lps.length - 1;
int resLeft = 0;
int resRight = res.length - 1;
int tmpLeft = 0;
int tmpRight = 0;
while (lpsLeft <= lpsRight) {
tmpLeft = chasLeft;
tmpRight = chasRight;
while (chas[chasLeft] != lps[lpsLeft]) {
chasLeft++;
}
while (chas[chasRight] != lps[lpsRight]) {
chasRight--;
}
set(res, resLeft, resRight, chas, tmpLeft, chasLeft, chasRight, tmpRight);
resLeft += chasLeft - tmpLeft + tmpRight - chasRight;
resRight -= chasLeft - tmpLeft + tmpRight - chasRight;
res[resLeft++] = chas[chasLeft++];
res[resRight--] = chas[chasRight--];
lpsLeft++;
lpsRight--;
}
return String.valueOf(res);
}
private static void set(char[] res, int resl, int resr, char[] chas, int ls, int le, int rs, int re) {
for (int i = ls; i < le; i++) {
res[resl++] = chas[i];
res[resr--] = chas[i];
}
for (int i = re; i > rs; i--) {
res[resl++] = chas[i];
res[resr--] = chas[i];
}
}
public static void main(String[] args) {
String str = "A1B21C";
String strlps = "121";
System.out.printf("The palindrome is: %s", getPalindrome2(str, strlps));
}
}
// ------ Output ------
/*
The palindrome is: AC1B2B1CA
*/
java的string后面添加内容 java字符串末尾添加字符
转载文章标签 java的string后面添加内容 添加最少字符使字符串整体都是 回文字符串 逆序 字符串 文章分类 Java 后端开发
-
Java-长字符串加密
加密:为你的长字符串提供最高级别的保护!!!
加密算法 JAVA -
java json字符串转 jsonobject
java json字符串转 jsonobject
JSON json 字符串转换