给定一个包含0-9和数字K之间的数字的数组,找到由数组中的数字构建的最小数字,使其大于K
例如,如果array = [0,1]
和K = 21
,则该计划应返回100
,0
,1
和10
小于21
和100
是仅由zeros
和ones
组成的第一个数字,大于21
。
我可以考虑一下蛮力方法,在那里我可以找到所有可能用数组中的数字创建的数字,然后找到大于K的最小数字,但我正在寻找一个更聪明和优雅的解决方案。你有什么建议吗?
答案 0 :(得分:0)
你能建立一个与给定数字相等的数字,除了最后一个更大的数字,是吗?
不是吗?那么,你可以建立一个与给定数字相等的数字,除了那个更大的十位数吗?
等等...
答案 1 :(得分:0)
<强>算法:强>
让我介绍一些变量:
k_digits
- 数字K
中的位数。
首先,我们可以观察到生成的数字会有k_digits
或k_digits + 1
。如果还不清楚的话,我最后会详细解释。
让我们假设答案会有k_digit
个数字。
我们可以将主要问题分成几个较小的(然后通过将解决方案与子问题相结合来获得初始问题的答案)。子问题的陈述听起来如下:
- 最小数字大于
K
没有最后一位数。- 我们可以编号
醇>K
而不是我们允许使用的数字的最后一位数吗?
让我们假设我们有解决这个问题的方法。然后我们需要找到最初问题的答案。我们可以通过以下方式执行此操作:
a)如果子问题2的答案为真(我们可以在没有最后一位数的情况下编写)。然后我们应该尝试将集合中最小的可用数字添加到该数字的末尾,使其大于K
。我们实际上做了什么 - 我们尝试用K
中较大的一个替换最初allowed set
的最后一个数字。我们称之为新号码 answer1
。
b)将集合中的最小可用数字添加到第一个子问题的数字末尾。由于其前缀较大,此数字将大于K
。我们将此号码称为answer2
。
c)在最后一步,我们应该比较answer1
(如果存在)和answer2
,并选择最小的。这将是最初问题的答案。
嗯,现在我希望我们很清楚如何结合子问题的答案。 那么,现在我将解释如何找到子问题的解决方案。
让我们从第二个子问题开始。这很容易 - 我们只是检查我们的allowed set
数字K
的所有数字(不包括最后一位)是否都有。
现在第一个子问题。您可能会注意到此子问题与初始问题相同,但K
较小。所以,我们可以递归地解决这个问题&#34;。这里的基本案例将是一位数K
。当我们只有一位数字时,我们可以直接说出答案 - 只需要搜索我们的数据集,使其大于K
的数字。
另外,请注意,在某些时候我们可能没有子问题1的答案。这意味着我们无法组成大于k_digits
的长度K
。但是,在这种情况下,我们总是可以使用k_digits + 1
来编号。只需从允许的集(k_digits + 1)
次中选择最小的数字。 特例:零。
示例:强>
allowed_set=[4,5]
K = 435
我们可以看到我们可以将我们的初始问题吐到子问题,其中K = 43
。
第二个子问题的解决方案是false
,因为我们不允许使用数字3
。我们将尝试以下列方式找到第一个子问题的解决方案 - 再次将其拆分为两个子问题,其中K = 4
。在这种情况下,第一个子问题的答案为5
,第二个子问题的答案为4
。我们可以将案例K = 43
的答案组成如下:answer1 = 44
,answer2 = 54
。 answer1
较小,因此,这实际上是K = 43
时案例的答案。然后,要查找K = 435
的答案,我们只能将4
添加到44
的末尾。所以答案是444
。
这可能不是最好的例子,但我希望它能说明我的答案。如果您有任何其他意见,请询问。
答案 2 :(得分:0)
我自己编程很新,大约有4个月的C ++经验,我们被赋予了与此相似的作业作为我们的作业问题之一,希望这有帮助!
//given array A of usable digits and assuming it is sorted
//meaning A[1] is the smallest
ans = 0;
//first we find the digits of K
//we use {} as Gauss
K_digits = {log(K)} + 1
numleft = K;
for i = 1 to K_digits
B[i] = {numleft/(10^(K_digits - i))}
numleft = numleft - B[i]*10^(K_digits - i)
//next we search through the array K_digits times
Max_seq = A[A.length] // max number in array
min_seq = A[1] // min number in array
usebigger = 0 // if this equals 1, we need to add an extra digit than K to be larger than K
copy = 0 //number of digits to copy, starting from left side
j = 1
while (j <= K_digits)
if Max_seq < B[j]
usebigger = 1
j = K_digits + 1 // end while loop
else if Max_seq == B[j]
copy = copy + 1
j = j + 1
else if Max_seq > B[j]
for t = 1 to A.length
if B[j] < A[t]
value = A[t]
break;
j = K_digits + 1
if copy == K_digits // can only manage to find a same valued number
usebigger = 1
//finally, with this info, we find the answer
if usebigger == 1 // need to add an extra digit than K to be larger than K
if min_seq == 0
for s = 1 to A.length
if A[s] > 0
min_num = A[S]
break;
ans = min_num*(10^K_digits)
else
for x = 0 to K_digits
ans = ans + min_seq*(10^x)
else
if copy != 0
for i = 1 to copy
ans = ans + B[i]*(10^(K_digits - i))
ans = ans + value*(10^(K_digits - copy - 1))
if copy+2 <= K_digits
for y = copy+2 to K_digits
ans = ans + min_seq*(10^(K_digits - y))
return ans