解决递归次数的算法

时间:2016-11-13 18:08:05

标签: algorithm

我需要找一个幸运数字"它包含相同数量的4和7位数(例如4747,4477等)。给定输入n,我需要找到最小的"幸运数字"它比大于,但最接近n(例如,如果输入是6060,那么答案将是7447)。解决这个问题的最佳算法是什么?假设输入将是< = 10 ^ 100000。我想把它分成字符,并在逻辑上解决它们,但有些情况下找出答案并不容易。谁能告诉我如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

以下算法具有最差情况线性时间,这是最佳的。

但是,这有点复杂;它涉及大量扫描,然后是另一种方式,然后是第一种方式。可能有一种更简单的算法也是最优的。 (一个现实的实现会增加一些小的优化来改善平均情况,和/或通过一个常数因子改善最坏情况的性能。)

  • 步骤1:处理结果需要比输入更多位数的情况。
    • 1a。如果 n (输入的长度)为奇数,则所需的结果为'444 ... 44777 ... 77',长度为 n 1。用该结果填充输出缓冲区,然后返回。
    • 1b。如果输入大于长度 n 的'777 ... 77444 ... 44',则所需的结果为'444 ... 44777 ... 77'长度 n +2。用该结果填充输出缓冲区,然后返回。
  • 步骤2:将输入复制到输出缓冲区。 (从现在开始,我们将直接在输出缓冲区上运行。)
  • 步骤3:将输出缓冲区变为仅包含4s和7s的最小整数,该整数大于或等于其当前值。 (例如,如果它是“4723”,那么我们想要“4744”。)为此,从左到右扫描(最高有效数字到最低有效数字),寻找不是4的第一个数字或7.(如果未找到此类数字,请继续执行步骤#4。)有三种情况,具体取决于此数字的值:
    • 案例0-3:如果此数字小于4,则将其更改,并将其右侧的每个数字更改为4。
    • 案例5-6:如果此数字为5或6,则将其更改为7,并将其右侧的每个数字更改为4。
    • 案例8-9:如果这个数字是8或9,那么再次向左扫描,找到第一个4.(我们知道必须有一个,因为否则我们会退出一步#1。)将4更改为7,并将之前的每个数字 - 4更改为4。
  • 步骤#4:将输出缓冲区变为由4s和7s的相等计数组成的最小整数,该计数大于或等于其当前值。 (例如,如果它是“4744”,那么我们想要“4747”。)
    • 4a:计算输出缓冲区中的4和7。
    • 4b:如果7s多于4s,那么计算需要将7s更改为4s才能使它们平衡。调用此 k 。从右到左继续,直到你“遇到” k +1 7s,然后向左继续直到遇到4.(我们知道必须有一个,因为否则我们会在步骤#1中退出。)将4改为7;然后将每个数字更改为之前的4到4的右边。然后,重新计算输出缓冲区中的4和7。 (注意:在这个子步骤之后,可能会有更多的4s而不是7s。例如,如果我们有“4777”,那么我们现在有“7444”。下一个子步骤将处理这个。)
    • 4c:如果4s多于7s,那么计算需要将多少7s更改为4s才能平衡它们。调用此 k 。从右到左进行。当您遇到4s时,将它们更改为7s,直到您将 k 4s更改为7s。