题目:
输入12345,找出全部的字典序排序(12345,12354,12435,12453···,21345···,31245···,41235···,51234···54321)。并且在所有字典序中,找出,满足序列2 1 5排序的最小的子序列
举例:12345不满足2 1 5
3 2 4 1 5满足,2 1 3 4 5也满足,相比较21345为满足要求的最小的子序列
思路:1.求出所有字典序排序(见博客Main38,输入abc,输出abc,acb,bac,bca,cab,cba);
2.过滤满足满足条件的子序列(见博客Main20,判断一个字符串是否为数值)
class WangYiYouDao {
//根据输入,通过字典序排序,获取所有输出
private static ArrayList<String> permutation(String str) {
ArrayList<String> list = new ArrayList<>();
if (str == null || str.length() == 0) {
return list;
}
char[] chars = str.toCharArray();
Arrays.sort(chars);//将字符数组按升序排列
list.add(String.valueOf(chars));//0.先将按升序排列后的字符串存入list中
while (true) {
int i = chars.length - 1;
int j = chars.length - 1;
//1.从字符数组最后一个字符开始往前遍历,寻找第一次chars[i-1]<chars[i]的位置
while (i >= 1 && chars[i - 1] >= chars[i]) {//i=2
i--;
}
if (i == 0) {//此时的数组已经是降序排列了(从右往左都是增的),表明全排列完成,cba这种
break;
}
//2.j从从最后一个位置开始,往前遍历,遇到大于chars[i-1]的值时停下
// 注意在遇到等于chars[i-1]的值的时候一定不要停下,不然会造成死循环(因为此时交换的是值相同的两个数)
while (j >= 0 && chars[j] <= chars[i - 1]) {
j--;
}
//3.
swap(chars, i - 1, j);//交换chars[i-1]和chars[j]的值
reverse(chars, i);//反转包括chars[i]元素在内到数组结尾的所有元素
list.add(String.valueOf(chars));
}
return list;
}
private static void reverse(char[] ch, int i) {
int left = i;
int right = ch.length - 1;
while (left <= right) {
char temp = ch[left];
ch[left] = ch[right];
ch[right] = temp;
left++;
right--;
}
}
private static void swap(char[] chars, int i, int j) {
char tmp = chars[i];
chars[i] = chars[j];
chars[j] = tmp;
}
public static void main(String[] args) {
List<String> list = new Main_38().permutation("12345");//得到所有字典序
String str = "2 1 5";
permit(list,str);
}
/**
* 过滤所有字典序,要求满足2 1 5这种顺序的,找出最小的满足条件的字典序
* 比如: 12345(不满足 2 1 5),比如 32415(满足 2 1 5)顺序,而且21345(也满足2 1 5)且21345是满足中的排在最前的
* @param list
* @param str
*/
private static void permit(List<String> list,String standard) {
if (list == null || list.size() == 0 || standard == null)return;
List<String> res = new ArrayList<>();//存所有满足2 1 5的字典序
for (String s : list) {
boolean exist2 = false;//表示2 已经出现过了,比如2(此时2出现了) 5(此时,exist2为true) 1 4 3
boolean exist1 = false;
boolean exist5 = false;
int j = 0;
for (j = 0; j < s.length(); j++) {
if (s.charAt(j) == standard.charAt(0)) {
exist2 = true;
} else if (s.charAt(j) == standard.charAt(2)) {
exist1 = true;
} else if (s.charAt(j) == standard.charAt(4)) {
exist5 = true;
}
if (exist1 && !exist2) {//1出现了,2还未出现,不满足 2 1 5这个条件
break;
}
if (exist5 && (!exist2 || !exist1)) {//5出现了,而2,1还没出现,不允许
break;
}
}
if (j == 5)//(j<4执行后j=5<5不满足)此时s合格,满足 2 1 5,比如 2 1 3 4 5(1出现之前,2出现了)(5出现之前2,1都出现了)
res.add(s);
}
Collections.sort(res);
System.out.println(res.get(0));
}
}