前几天找工作,笔试下面这道题:
把1,2,3,4,5,6,7,8,9共九个数分成三组构成排列a1a2a3,a4a5a6,a7a8a9,而且每个数字使用有且仅有一次,构成的排列之比为3:2:1,求输出所有的排列组合。
方法一:
显然a1a2a3,a4a5a6,a7a8a9在[123, 987]内,进一步就是a1a2a3在[123,329],遍历即可
public static void test1(){
long e1 = System.currentTimeMillis();
for(int i = 123; i <= 329; i ++){
if(match(i, 2*i, 3*i)){
System.out.println(i + " " + 2*i + " " + 3*i);
}
}
long e2 = System.currentTimeMillis();
System.out.println("time:" + (e2 - e1));
}
public static boolean match(int first, int second, int third) {
List<Integer> list = Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0);
int index = -1;
String str = first + "" + second + "" + third;
for(int i = 0; i < str.length(); i ++){//遍历每一个字符,在list中记录对应字符出现的次数
index = Integer.parseInt(str.substring(i, i + 1)) - 1;//index为零则是取到字符0,需要过滤掉
if(index < 0 || index > 8){//过滤
return false;
}
if(list.get(index) >= 1){
return false;
}else{
list.set(index, list.get(index) + 1);
}
}
return true;
}
结果:
192 384 576
219 438 657
273 546 819
327 654 981
time:1
方法二:
使用正则表达式过滤
public static void test1() {
long e1 = System.currentTimeMillis();
Pattern pattern = Pattern.compile(//不重复字符组成的九位数
"([1-9])"
+ "(?!\\1)([1-9])"
+ "(?!\\1|\\2)([1-9])"
+ "(?!\\1|\\2|\\3)([1-9])"
+ "(?!\\1|\\2|\\3|\\4)([1-9])"
+ "(?!\\1|\\2|\\3|\\4|\\5)([1-9])"
+ "(?!\\1|\\2|\\3|\\4|\\5|\\6)([1-9])"
+ "(?!\\1|\\2|\\3|\\4|\\5|\\6|\\7)([1-9])"
+ "(?!\\1|\\2|\\3|\\4|\\5|\\6|\\7|\\8)([1-9])$");
String str = "";
Matcher match = null;
for (int i = 123; i <= 329; i++) {
if (3 * i >= 1000) {
break;
}
str = Integer.toString(i * 1000000 + i * 2 * 1000 + 3 * i);
match = pattern.matcher(str);
if (match.matches())
System.out.println(i + " " + 2 * i + " " + 3 * i);
}
long e2 = System.currentTimeMillis();
System.out.println("time:" + (e2 - e1));
}
结果:
192 384 576
219 438 657
273 546 819
327 654 981
time:3