2020-11-18,快速从字符串数组中找出符合要求的两个数字

给定一个数字字符串数组,要求选取其中任意两个字符串两两组合,选取的字符串中包含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 strToInt(String numStr) {

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 intsI, List intsJ) {

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;

}

你可能感兴趣的:(2020-11-18,快速从字符串数组中找出符合要求的两个数字)