问题描述:
给一个定长为N的字符串S,构造一个字符串T,长度也为N。起初,T是一个空串,随后反复进行下列任意操作
- 从S的头部删除一个字符,加到T的尾部
- 从S的尾部删除一个字符,加到T的尾部
目标是最后生成的字符串T的字典序尽可能小
1≤N≤2000
字符串S只包含大写英文字母
输入:
字符串S
输出:
字符串T
样例表示:
输入:ACDBCB
输出:ABCBCD
思路分析:
只需要定义两个指针,分别指向开始和结尾,然后判断若开始的字符小于结尾的字符,则直接将开始的字符加入到T(StringBuilder)中,并将开始指针加一;若开始的字符大于解为的字符,则直接将结尾的字符加入到T中,然后将结尾指针减一;若二者相等,则看里面的具体情况。
具体看代码注释:
import java.util.Scanner;
public class Zdxzx {
//字典序最小问题
public static StringBuilder solve(String a)
{
StringBuilder temp=new StringBuilder(a);
StringBuilder out=new StringBuilder();
int st=0;//开始指针
int et=temp.length()-1;//结束指针
while(st<et) {
if (temp.charAt(st) < temp.charAt(et))//当开始小于末尾字符
{
out.append(temp.charAt(st));//加入到新字符串中
st++;//指针后移
} else if (temp.charAt(st) > temp.charAt(et))//末尾小于开始字符
{
out.append(temp.charAt(et));
et--;
} else//开始和末尾相等
{
int tempst = st + 1;//建立两个临时变量记录两个指针
int tempet = et - 1;
while (tempst <tempet)//不断循环
{
if (temp.charAt(tempst) > temp.charAt(tempet))末尾小于开始字符
{
out.append(temp.charAt(et));
et--;
break;
} else if (temp.charAt(tempst) < temp.charAt(tempet))//当开始小于末尾字符
{
out.append(temp.charAt(st));
st++;
break;
} else //开始等于末尾字符
{
tempst++;
tempet--;
}
}
}
}
return out.append(temp.charAt(st));
}
public static void main(String[] args) {
Scanner a=new Scanner(System.in);//输入
String b=a.nextLine();
StringBuilder s=solve(b);
System.out.println(s);//结果输出
}
}
运行效果截图: