Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 查找数字的任何排列是否在范围内_Algorithm_Permutation - Fatal编程技术网

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

Algorithm 查找数字的任何排列是否在范围内,algorithm,permutation,Algorithm,Permutation,我需要找到在指定范围内是否存在任何数字排列,我只需要返回Yes或No 例如:Number=122,和Range=[200250]。答案是是,因为221存在于该范围内 附言: 对于我手头的问题,需要搜索的号码 将只有两个不同的数字(仅包含1和2, 例:111222121) 这不是一个家庭作业问题。这是在一次采访中被问到的 我建议的方法是找到给定数字的所有排列并进行检查。或者在范围内循环并检查是否找到任何数字的排列 检查每一个排列都太昂贵而且没有必要 首先,你需要把它们看作字符串,而不是数字 将每个

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

例如:
Number=122
,和
Range=[200250]
。答案是
,因为221存在于该范围内

附言:

  • 对于我手头的问题,需要搜索的号码 将只有两个不同的数字(仅包含1和2, 例:111222121)
  • 这不是一个家庭作业问题。这是在一次采访中被问到的
  • 我建议的方法是找到给定数字的所有排列并进行检查。或者在范围内循环并检查是否找到任何数字的排列

  • 检查每一个排列都太昂贵而且没有必要

    首先,你需要把它们看作字符串,而不是数字

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

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


    现在将这些依赖项和独立项建模为一个图。由于情况(c)很少见,因此很容易按照O(10N)=O(N)的比例进行时间搜索。

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

    如果你的数字中有6个1和4个2,那么首先你有间隔

    [1111112222;222111111]

    如果您的范围没有与此间隔重叠,则完成。现在把这个间隔在中间,你得到

    (1111112222+22211111)/2

    现在找到由小于拆分点的相应数字的1和2组成的最大数字。(可能这一步可以通过以1和2的有效方式直接计算分裂或通过将1和2解释为二进制数的0和1来改进,也可以考虑取两个数的几何平均值,因为候选者可以在左和右之间更均匀地分布。) 编辑:我想我已经知道了:假设边界具有形式PQ和PR(即P是一个共同的前缀),然后从Q和R建立一个对称的字符串S,在字符串的开始和结束时,1个在中间,2个在中间,以PS作为分割点(因此,从111111到2222和1122221111,你将建立111122222211,前缀是p= 11)。 如果此数字包含在范围内,则完成


    如果不是,请查看范围是否高于或低于[old lower bound;split]或[split;old upper bound]并重复此操作。

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

    对于给定的值为KXXXX的a,其中K是给定的,我们可以
    推断K0000假设给您的范围是:ABC和DEF(每个字符都是一个数字)

    存在算法置换(范围开始、范围结束、范围索引、nos1、nos2)
    如果(nos1>0且范围开始[范围索引]<1<范围结束[范围索引],且
    存在排列(范围开始、范围结束、范围索引+1、nos1-1、nos2))
    返回真值
    elif(nos2>0且范围开始[范围索引]<2<范围结束[范围索引]和
    存在排列(范围开始、范围结束、范围索引+1、nos1、nos2-1))
    返回真值
    其他的
    返回错误
    
    我假设每个数字都是一系列数字。给定的数字表示为
    {numberOf1s,numberOf2s}
    。我试图将数字(先是1s,然后是2s)拟合到范围内,如果不是,程序将返回false

    PS:我可能真的错了。我不知道这类事情能否奏效。我没怎么想,真的

    更新


    我表达算法的方式是错误的。需要对其进行一些更改。这是一个有效的代码(它适用于我的大多数测试用例):

    您实际上只需要检查最多两个可能的排列


    假设您的输入数字仅包含数字X和Y,您是否询问一般方法,或如何实现您的想法?我认为对所有排列进行循环是合理的。例如,示例编号的排列数为:10/6!/4! = 21010位字符串的绝对最坏情况是252。你能详细说明一下吗?我的组合/离散知识是有限的,但我不知道如何在不列举所有排列(或最终得到一个庞大的方程组?)的情况下确定(a)、(b)和(c)。你可以直接根据范围计算a、b和c。例如200..250。100s数字=0,1,3,4,…9始终无效。100s=2始终有效。10s是0,1,2,3,4,5有效,6,7,8..9无效,依此类推!我的想法正好相反。就像把一组排列看作一组变量。这更有意义。谢谢你的澄清:)。谢谢,我想我得到了你建议的方法。它应该很好用。谢谢你的帮助。@AndrewTomazos深究我在发布我的答案后看到了你的答案。你能看看我在下面贴的东西吗。本质上是一样的吗?我不想要多余的答案;如果是,我将删除它。:)如果范围是[123;220],我不确定该算法是否有效。首先可以是1或2。取1,秒必须大于或等于2,我们有一个2。让我们试试,第三个必须大于3:矛盾。回溯,我们已经尝试了所有第二个值,回溯。现在试着用2来表示第一个值,第二个值可以是0,1,2,我们有一个1和一个2。尝试1,任何值都适用于第三个,剩下的值为2。答案是肯定的,排列是212。我认为回溯的时间代价可能很高。一般来说是的,但这里只有两个可能的值,大多数情况下,我们会比较早地发现矛盾。除非我们使用启发式,否则我认为
    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