我怎样才能find在一个范围内随机非重复整数string中的缺less整数

即使开始考虑如何做到这一点,我也遇到了麻烦。

我需要find一个没有分隔符的随机数字串中缺less的数字。

这里是一个例子: 14036587109 。 在这个例子中,缺less的数字是2 ,范围是0-10 (含)。

我怎样才能编写一个JavaScript / Node.JS程序来解决这个问题?

我无法弄清楚的是该程序是如何分离数字的; 在上面的例子中,程序如何知道数字10 (在最后一个数字之前)不是数字10

关于缺less的整数我们知道两件事情:input中的总位数告诉我们缺失整数中的位数,并且(在评论中提到的@samgak)计数input中每个数字的出现我们哪个数字缺less的整数是由。 这可能会给我们一个解决scheme的快速path,如果input中缺less这些数字的排列之一。 如果没有,那么:

从最高位数到最低位数找出整数; 如果范围是例如0-999,那么先search3位整数,然后search2,然后search1。

如果一个整数只在input中的一个位置出现,将其标记为已find,并将其从input中删除。

然后,从尚未find的最长整数开始,看看两个地方存在的整数。 尝试两个选项,然后检查是否所有依赖我们使用的数字的其他整数也存在; 例如,如果357位于两个位置:

 ... 1235789 ... 2435768 ... 357 357 23 43 123 243 235 435 578 576 78 76 789 768 

当尝试357的第一个位置时,检查23,123,235,578,78和789是否有另外的可能性。对于第二个位置,检查43,243,435,576,76和768。

如果这些检查显示只有其中一个选项可行,请将该号码标记为已find,并将其从input中删除。

继续做这个更短的整数,以及在3,4,…位置的整数。 如果在这样做之后,仍然没有结果,那么可能需要recursion地尝试几个选项,这将很快导致大量的选项。 (特别是大规模的input,可能会阻止这种方法,使其不可能慢)。但随机input的平均复杂度可能是不错的。


实际上,当你发现一个只存在于input的一个位置的整数,但它是一个丢失的数字的排列,你不应该删除它,因为它可能是缺失的整数。 因此,该algorithm可能是:删除所有可以明确定位在input中的整数,然后尝试逐个删除所有可能丢失的整数,并查找不一致性(即其他缺less正确长度或数字的缺失数字)。


当然,这都是启发式的问题。 你尝试一些简单的方法,如果这样做不行,你可以尝试一些更复杂的方法,如果这样做不行的话,你可以尝试一些更复杂的方法…每一步都有几个选项,每一个都是最优的inputstring,但不为别人。

例如,如果范围是0-5000,那么首先标记只出现在一个位置的4位整数。 但之后,你可以再次做同样的事情(因为两次出现的整数可能会有一个选项被删除),直到没有更多的改进,或者你可以检查两次存在的整数或整数x次,或移动到3位整数…我不认为有一个简单的方法来知道哪些选项会给出最好的结果。

这个解决scheme应该适用于任何inputstring和任何开始/结束范围:

我们可以将string中的数字看作我们可以select的数字池。 我们从startRange开始,到endRange ,在我们的数字池中查找每个数字。

当我们find一个可以由我们的数字池组成的数字时,我们从我们的数字池中删除这些数字,因为这些数字已经被用来在我们的范围内形成一个数字。

只要我们遇到一个不能由我们的数字池组成的数字,那一定是缺失的数字。

 const str = "14036587109"; // input const numsLeft = str.split("").map(num => parseInt(num)); // array of numbers const startRange = 0; const endRange = 10; for(let i = startRange; i <= endRange ; i++) { // check if number can be formed given the numbers left in numsLeft const numFound = findNum(numsLeft, i); if(!numFound) { console.log("MISSING: " + i); // prints 2 break; } } function findNum(numsLeft, i) { // array of digits const numsToFind = String(i).split("").map(num => parseInt(num)); // default is true, if all digits are found in numsLeft let found = true; numsToFind.forEach(num => { // find digit in numsLeft const numFoundIndex = numsLeft.indexOf(num); if(numFoundIndex < 0) { // digit was not found in numsLeft found = false; return; } else { // digit was found; delete digit from numsLeft numsLeft.splice(numFoundIndex, 1); } }); return found; } 
 var input = '10436587109'; var range = [10,9,8,7,6,5,4,3,2,1,0]; var expr1 = new RegExp(range.join('|'),'g'); var expr2 = new RegExp('[0-9]','g'); var a = input.match(expr1).map(Number).concat(input.match(expr2).map(Number)); var x = range.filter(function(i){ return a.indexOf(i)===-1; });