记录一道算法题:如下
根据字符序列0123456789abcdefghijklmnopqrstuvwxyz,按照序列顺序穷举生成一个N位小写字母和数字组合(N>1),每生成一个组合,不能全是字母或者全是数字。(例如用Java实现或者其它)
全身数字的情况,或者全是字母,则不行:
1111,222,01,aaaa,abcd,eb
数字和字母混合则可以:
a00,00a,aa1,ce2f
例如:
N =3
调用第一次
00a
调用第二次,输出:
00b
调用第三次,输出:
00c
当时考虑的是如果是N=2,可以把字符序列变为数组或者集合,然后遍历两个数组/集合就可以了(然后经过正则表达式处理),让给N=3,可以三个遍历,但是如果是N个的话,就没办法直接N个遍历了,
后来想到的是
(草图)
主要是for循环递归,通过递归方式,把n阶循环转变到2层for循环
应该可以完成N个for循环,代码如下(实现思路和代码)
public static void recursionFor2() {
Map<Integer, Set<String>> map = new HashMap<>();
// String[] l1 = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
// String[] l2 = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
// String[] l3 = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
String[] l1 = {"0","1","2"};
String[] l2 = {"0","1","2"};
String[] l3 = {"0","1","2"};
map.put(1, new HashSet<>(Arrays.asList(l1)));
map.put(2, new HashSet<>(Arrays.asList(l2)));
map.put(3, new HashSet<>(Arrays.asList(l3)));
List<String> xx = getAllStrings(map);
System.out.println(xx.size());
System.out.println(xx);
}
public static List<String> getAllStrings(Map<Integer, Set<String>> map){
if(map.size() == 2){
List<String> result = new ArrayList<>();
Set<Integer> tagTypeSet = map.keySet();
Iterator<Integer> iterator = tagTypeSet.iterator();
Integer tag1 = iterator.next();
Integer tag2 = iterator.next();
Set<String> set1 = map.get(tag1);
Set<String> set2 = map.get(tag2);
for (String tagId1 : set1) {
for (String tagId2 : set2) {
String string = new String();
string = tagId1+tagId2;
result.add(string);
}
}
return result;
}else {
List<String> result = new ArrayList<>();
Set<Integer> keySet = map.keySet();//获取key值
System.out.println("tagTypeSet = " + keySet);
Iterator<Integer> iterator = keySet.iterator();//
System.out.println("iterator = " + iterator);
if(iterator.hasNext()){
Integer tagValue = iterator.next();
System.out.println("iterator.next() = " + tagValue);
Set<String> set = map.get(tagValue);
Map<Integer, Set<String>> newMap = new HashMap<>();
newMap.putAll(map);
newMap.remove(tagValue);
List<String> oneResult = getAllStrings(newMap);
for (String stringMap: oneResult){
for (String tagId : set){
String string = new String();
string = stringMap+tagId;
result.add(string);
}
}
}
return result;
}
}
用 数组{"0","1","2"}进行验证,可以得到
[000, 001, 002, 010, 011, 012, 020, 021, 022, 100, 101, 102, 110, 111, 112, 120, 121, 122, 200, 201, 202, 210, 211, 212, 220, 221, 222]
结果正常.
以上方法主要是for循环递归,通过递归方式,把n阶循环转变到2层for循环
这里暂时没考虑到时间空间复杂度,后续可以继续优化