查找数字的任何排列是否在一个范围内

时间:2012-06-03 09:20:58

标签: algorithm permutation

我需要查找在指定范围内是否存在数字的任何排列,我只需要返回是或否。

例如:Number = 122Range = [200, 250]。答案是Yes,因为221存在于范围内。

PS:

  1. 对于我手头的问题,要搜索的号码 将只有两个不同的数字(它只包含1和2, 例如:1112221121)。
  2. 这不是一个家庭作业问题。有人在接受采访时被问及。
  3. 我建议的方法是找到给定数字的所有排列并检查。或者遍历范围并检查我们是否找到了数字的任何排列。

5 个答案:

答案 0 :(得分:4)

检查每个排列是太昂贵和不必要的。

首先,您需要将它们视为字符串,而不是数字,

将每个数字位置视为一个单独的变量。

考虑每个变量可以容纳的可能数字集如何受范围限制。每个数字/变量对将是(a)始终有效(b)始终无效;或(c)其有效性有条件地取决于具体的其他变数。

现在将这些依赖关系和独立性建模为图形。由于情况(c)很少,因此很容易按时间搜索O(10N)= O(N)

答案 1 :(得分:2)

数字有一个很好的属性,我认为可以帮助你:

  

对于给定数字 a 的值KXXXX,其中给出了K,我们可以   推导出K0000< = a< K9999。

使用此属性,我们可以尝试构建范围内的排列:

我们举个例子:

范围= [200,250]

数字= 122

首先,我们可以定义第一个数字必须是2.我们有两个2,所以到目前为止我们都很好。

第二个数字必须在0到5之间。我们有两个候选人,1和2.还不错。 让我们检查第一个值1:

这里任何数字都会很好,我们仍然有一个未使用的2.我们找到了我们的排列(212),因此答案是

如果我们确实发现了与值1的矛盾,我们需要回溯并尝试值2,依此类推。

如果所有解决方案均无效,请返回

此算法可以使用回溯来实现,并且应该非常高效,因为您只有2个值来测试每个位置。 该算法的复杂性为2 ^ l,其中l是元素的数量。

答案 2 :(得分:0)

你可以尝试实现某种二进制搜索:

如果你的号码中有6个和4个,那么首先你有间隔

[1111112222; 2222111111]

如果您的范围与此间隔不重叠,则表示您已完成。现在在中间分割这个间隔,你得到

(1111112222 + 222211111)/ 2

现在找到最大数字,该数字由相应数字的1和2组成,小于分割点。 (可能通过基于1和2以某种有效的方式直接计算分割或通过将1和2解释为二进制数的0和1来改进这一步骤。还可以考虑采用两个数的几何平均值,因为候选人可能会在左右之间更均匀地分配。)

[编辑:我想我已经知道了:假设边界有pq和pr的形式(即p是一个公共前缀),然后从q和ra对称字符串s构建,开头和结尾都是1字符串和中间的2并将ps作为分割点(因此从1111112222和1122221111建立111122222211,前缀是p = 11)。]

如果此数字包含在范围内,则表示您已完成。

如果不是,请查看范围是高于还是低于,并使用[旧下限;拆分]或[拆分;旧上限]重复。

答案 3 :(得分:0)

假设给你的范围是:ABC和DEF(每个字符都是一个数字)。

Algorithm permutationExists(range_start, range_end, range_index, nos1, nos2)

     if (nos1>0 AND range_start[range_index] < 1 < range_end[range_index] and
          permutationExists(range_start, range_end, range_index+1, nos1-1, nos2))
               return true
     elif (nos2>0 AND range_start[range_index] < 2 < range_end[range_index] and
          permutationExists(range_start, range_end, range_index+1, nos1, nos2-1))
               return true
     else
               return false

我假设每个数字都是一系列数字。给定的数字表示为{numberOf1s, numberOf2s}。我试图在范围内拟合数字(前1s然后2s),如果不是,则procudure返回false。

PS:我可能真的错了。我不知道这种事情是否可行。我没有多想,真的..

<强>更新

我表达算法的方式不对。需要在其中进行一些更改。这是一个有效的代码(适用于我的大多数测试用例):http://ideone.com/1aOa4

答案 4 :(得分:0)

你真的只需要检查最多两种可能的排列。

假设您的输入数字仅包含数字X和Y,其中X 我会忽略你用完一位数或其他数字的所有特殊情况。

阶段1:处理公共前缀。

设A是范围下限的第一个数字,让B为范围上限的第一个数字。如果A

否则,A = B.如果X = A = B,则使用X作为置换的第一个数字,并在下一个数字上重复第1阶段。如果Y = A = B,则使用Y作为置换的第一个数字,并在下一个数字上重复第1阶段。

如果X和Y都不等于A和B,则停止。答案是否定。

阶段2:使用公共前缀完成。

此时,A

否则,请检查以下四种情况。最多有两个案例需要真正的工作。

  • 如果A = X,那么尝试使用X作为排列的第一个数字,然后是所有Y,接着是X的其余部分。换句话说,使剩余的排列尽可能大。如果这种排列在范围内,那么答案是肯定的。 如果此排列不在范围内,那么从X开始的排列就不会成功。
  • 如果B = X,那么尝试使用X作为排列的第一个数字,然后是X的其余部分,接着是所有的Y.换句话说,使排列的其余部分尽可能小。如果这种排列在范围内,那么答案是肯定的。 如果此排列不在范围内,那么从X开始的排列就不会成功。
  • 类似情况,如果A = Y或B = Y。

如果这四个案例都没有成功,那么答案是否定的。请注意,最多一个X案例中的一个案例和最多一个Y案例可以匹配。

在这个解决方案中,我假设输入数字和范围内的两个数字都包含相同的位数。通过一些额外的工作,该方法可以扩展到数字位数不同的情况。

相关问题