给定一个数字字符串数组,要求选取其中任意两个字符串两两组合,选取的字符串中包含0-9的所有数字,找出符合要求的组合的总数
例如:
123456,112233445566,123789,546821,025975,15840911115600,5454545454522222211111
说明:
该问题的难点在于当给定数字字符串较多时,例如10万个字符串,判断时间容易较长,必须进行优化,短时间内给出结果
解决思路:
将给定字符串数组全部转换为数字组合的数组
例如:字符串123456,可以转换为1,2,3,4,5,6的集合
字符串,112233445566也可以转换为1,2,3,4,5,6的集合
这样我们只需对1,2,3,4,5,6的集合进行判断,这样会大大降低运算的数量
// Complete the winningLotteryTicket function below.
//数字字符串数组,两两组合,包含0-9的所有数字,找出符合要求的组合的总数
static long winningLotteryTicket(String[] tickets) {
Map, Integer> map =new HashMap<>();
//解析所有字符串为数字集合并计数,这么处理会极大的降低需要处理的集合的数量
//此方法在数据量极大时,会大幅度降低需要处理的数据的数量
Arrays.stream(tickets)
.forEach(ticket -> {
List numList =strToInt(ticket);
Integer cnt =map.get(numList);
cnt =null == cnt ?0 : cnt;
cnt++;
map.put(numList, cnt);
});
List> list =new ArrayList<>(map.keySet());
//集合中数字两两判断,是否包含0-9的所有数字
//注:若单个结合本身就包含0-9的所有数字,需要做特殊处理
long totalSum = IntStream.range(0, list.size())
.mapToLong(i -> {
List listA =list.get(i);
long
countA =map.get(listA);
if
(isHasAll(listA)) {
long sum = IntStream.range(i +1, list.size())
.mapToLong(a ->map.get(list.get(a)))
.sum();
long
total = countA * sum;
total += LongStream.range(1, countA)
.sum();
return
total;
}
long sum = IntStream.range(i +1, list.size())
.filter(j ->isHasAll(listA, list.get(j)))
.mapToLong(j ->map.get(list.get(j)))
.sum();
return
countA * sum;
})
.sum();
return
totalSum;
}
/**
* 字符串转换为数字集合,需去重,排序
*@param numStr
* @return
*/
private static List
return IntStream.range(0, numStr.length())
.map(i -> Integer.
parseInt(numStr.substring(i, i + 1)))
.distinct()
.sorted()
.boxed()
.collect(Collectors.
toList());
}
/**
* 判断两个数字结合是否包含0-9的所有数字
* @paramintsI
* @param intsJ
* @return
*/
public static boolean isHasAll(List
int[] buffer = IntStream.rangeClosed(0, 9)
.filter(i -> !
intsI.contains(i))
.toArray()
;
int[] result = Arrays.stream(buffer)
.filter(i -> !
intsJ.contains(i))
.toArray()
;
return null== result || result.length == 0;
}
/**
* 判断单个数字结合是否包含0-9的所有数字
* @paramintsI
* @return
*/
public static boolean isHasAll(List intsI) {
int[] result = IntStream.rangeClosed(0, 9)
.filter(i -> !
intsI.contains(i))
.toArray()
;
return null== result || result.length == 0;
}