给定来自K个连续整数的每个数字的数字恢复序列

时间:2016-05-02 16:35:05

标签: algorithm

写下从copy your_created_table FROM '/your/path/to/file.csv' USING DELIMITERS ',' CSV; 开始的一系列N个连续正整数。然后,选择每个数字中的一个数字并以相同的顺序写入。我们需要找到满足一系列数字的最小X

X并且输入一系列数字作为输入。我试图找到一些数学见解,但失败了。 N可以大到10 ^ 5。

换句话说,给定和长度为N的数组A包含数字,我们需要找到一个长度为N的数组B,其中包含连续的正整数(B [i + 1] = B [i] + 1),这样数字A [i]可以在数字B [i]中找到,B [0]是最小的。 (B中没有数字包含前导0)。

例如:如果给出9,2,1,2,2,那么最小的X是19(19,20,21,22,23)。

另一个例子:如果给出9 8 9 1 0那么这样的序列将是97 98 99 100 101.看到你可以在给定的序列中找到这个系列中相应数字的数字。 97是可能的最小起始数(1097也足够但不是最小的起始数)。

任何关于如何处理此问题以及此类问题的提示都会有所帮助。

2 个答案:

答案 0 :(得分:0)

这是一个O(N^2) - ish算法,可能会或可能不够好,因为您没有链接原始问题,因此详细要求未知。

我将在下面假设N = 100000

For every y in [0, 100000):
    Consider the case that B[0] = 100000 * x + y for some x.
    This will be equivalent to requiring that x contains some of the digits in [0, 10),
    and that x + 1 contains some of the digits in [0, 10),
    from which a smallest x can easily be found (or pre-computed).
    (But the special case x = 0 needs further attention, problem of leading zero.)
Find the maximun of all 100000 * x + y found above, which is the answer.

还有进一步的优化,具有相似的想法(例如,不是查看最后五位数,而是可以查看最后三位数,等等)。但我现在不会发布这些细节。

答案 1 :(得分:0)

这就是你手动解决第一个例子的方法:

  

示例:9,2,1,2,2

→数字不超过5位数。

  

9,2

9和2是不同的,而不是连续的→它们处于不同的位置:

9****, *2***  
  

9,2,1

1可以跟随9,但前提是它们处于最低位置(单位):

****9, 2***0, 2***1  
9****, *2***, **1**  
  

9,2,1,2

2可以跟随9和/或1,但只能在最低位置(单位);它也可能与前面的2位置相同,但不在最低位置:

****9, 2***0, ****1, ****2  
****9, 2***0, ****1, 2***2  
****9, 2***0, ****1, *2**2  
****9, 2****, *1***, ****2  
9****, *2***, ****1, ****2  
9****, *2***, **1**, *2***  
9****, *2***, **1**, ***2*  
  

9,2,1,2,2

2可能与之前的2个中的一个或两个处于同一位置,但不在最低位置(单位):

****9, 2***0, ****1, ****2, 2***3   min. 2 digits   19, 20, 21, 22, 23
****9, 2***0, ****1, ****2, *2**3   min. 3 digits  
****9, 2***0, ****1, 2***2, 2***3   min. 2 digits   19, 20, 21, 22, 23
****9, 2***0, ****1, 2***2, *2**3   min. 3 digits  
****9, 2***0, ****1, *2**2, 2***3   min. 3 digits  
****9, 2***0, ****1, *2***, **2*3   min. 4 digits  
****9, 2***0, *1**1, ****2, 2***3   min. 3 digits  
****9, 2***0, *1**1, ****2, **2*3   min. 4 digits  
9****, *2***, ****1, ****2, *2**3   min. 3 digits  
9****, *2***, ****1, ****2, **2*3   min. 4 digits  
9****, *2***, **1**, *2***, *2***   min. 3 digits  
9****, *2***, **1**, *2***, ***2*   min. 4 digits  
9****, *2***, **1**, ***2*, *2***   min. 4 digits  
9****, *2***, **1**, ***2*, ****2   min. 5 digits  

限制尝试可能性的数量的关键当然是首先遵循最有希望的(即最低位数)路径,正如我们为第二个例子所做的那样:

  

示例:9,8,9,1,0

→数字不超过5位数。

  

9,8

8只能处于与9不同的位置:

9****, *8***   min. 2 digits
  

9,8,9

9可以与9相同(不是最低)位置,或者与8相同(最低)位置:

9****, 98***, 9****   min. 2 digits
9***7, ****8, ****9   min. 2 digits
  

9,8,9,1

1不能与任何其他数字位于同一位置:

9****, 98***, 9****, **1**   min. 3 digits
9***7, ****8, ****9, *1**0   min. 3 digits
  

9,8,9,1,0

0可以在9个中的一个或两个之后出现,但不是在最低位置:

9****, 98***, 9****, **1**, 0****   min. 3 digits   97, 98, 99, 100, 101
9***7, ****8, ****9, *1**0, 0***1   min. 3 digits   97, 98, 99, 100, 101

所以可能的算法是:

  • 对于每个新数字,检查它是否可以跟随任何前面的数字,以及在哪个位置(1→2可能在每个位置发生,但1→2→3或1→x→x→4仅在最低位置; 1→1可以发生在除最低位置之外的任何位置)。
  • 首先检查最有希望的路径,即新数字是否可以与前一个数字位于同一位置。
  • 如果新数字不能跟随任何前面的数字,则只考虑一个额外的位置(即解决方案中的最小位数增加)。
  • 如果您只找到大型解决方案,请回溯并选择当时看起来不太有希望的路径。

我不确定您是否能够在开始回溯后找出最小的解决方案。如果您找到一个 n 位的解决方案,那么您应该检查所有 n 位数的解决方案。