【问题标题】:algorithm proof - building least number after deleting k digits from an n-digit number算法证明 - 从 n 位数字中删除 k 位数字后构建最少数字
【发布时间】:2015-06-16 08:49:11
【问题描述】:

问题:给定一个n位数,应该删除其中的k(k

解决方案:删除大于或等于其右邻居的第一个数字(从左到右),或者如果我们找不到这样的数字,则删除最后一个数字。重复此过程k 次。 (参考codecareer。还有geeksforgeeksstackoverflow等其他解决方案,但我觉得这里描述的更直观,所以我更喜欢这个。)

现在的问题是,如何证明上面的解决方案是正确的,即如何在每一步删除一个数字后使其最小,从而保证最终的数字是最小的。

【问题讨论】:

  • 允许在左边的数字前导零。例如删除‘1028’中的一位,左边的数字是‘028’。

标签: algorithm proof


【解决方案1】:

假设k = 1

m = Σ<sub>i=0,...,n</sub> a<sub>i</sub>b<sup>i</sup>n+1 数字编号a<sub>n</sub>a<sub>n-1</sub>...a<sub>1</sub>a<sub>0</sub> 带有基数b,即0 ≤ a<sub>i</sub> &lt; b ∀ 0 ≤ i ≤ n(例如b = 10)。

证明

∃ j &gt; 0a<sub>j</sub> &gt; a<sub>j-1</sub> 并让 j 最大。
这意味着a<sub>j</sub> 是(严格来说不是必需的)连续数字递增序列的最后一位。 然后数字 a<sub>j</sub> 现在从数字中删除,结果数字 m' 具有值

m' = Σi=0,...,j-1 aibi + Σi=j+1 ,...,n aibi-1

这种减少的目的是最大化差异m-m'。那么让我们来看看:

m - m' = Σi=0,...,n aibi - (Σi=0, ...,j-1 aibi + Σi=j+1,...,n a ibi-1) = ajbj + Σi=j+1,...,n (aib i - aibi-1) = anbn + Σi=j,...,n-1 (ai - ai+1)bi

j 有没有更好的选择来获得更大的差异?

  • 由于a<sub>n</sub>...a<sub>j</sub> 是一个递增的子序列,所以a<sub>i</sub>-a<sub>i+1</sub> ≥ 0 成立。所以选择j' &gt; j而不是j,你会得到更多的零,你现在有一个正数,即差异不会更大,但如果存在ia<sub>i+1</sub> &lt; a<sub>i</sub>(严格更小),则差异会更低。
  • j 应该是最大的,即a<sub>j-1</sub>-a<sub>j</sub> &lt; 0。我们知道
    bj-1 > Σi=0,...,j-2(b-1)bi = b i-1-1
    这意味着,如果我们选择 `j'

如果 ∄ j &gt; 0a<sub>j</sub> &gt; a<sub>j-1</sub> 以上证明适用于 j = 0

还有什么事情要做?

这只是证明您的算法适用于k = 1

可以将上述证明扩展到(严格来说不是)递增数字的多个子序列。由于您需要的索引数量,它是完全相同的证明,但可读性要差得多。

也许你也可以使用归纳法,因为数字之间没有相互作用(阻止下一个选择或其他东西)。

【讨论】:

  • 多次删除的正确性证明对我来说是困难的部分,我会根据您的分析检查它是否与单个删除相同。
  • @zhangwt 使用归纳法,你马上就到了最后:你得到的最小数字少了一位。如果k &gt; 1,您继续使用k' = k - 1。你得到一个数字序列,使得数字总是减 1,并且这个数字总是你可以通过删除一个数字从前一个数字中得到的最小数字。这证明您的算法对于k &gt; 1 是正确的。
  • 我认为上面的归纳过程中有一个隐含的假设,需要证明。作为归纳范式,假设在删除j (j&lt;k) 之后,剩下的数字是当前最小的,比如A&lt;sub&gt;j&lt;/sub&gt;,即n-j 位数。在执行j+1删除时,我们根据A&lt;sub&gt;j&lt;/sub&gt;得到A&lt;sub&gt;j+1&lt;/sub&gt;,实际上这是我们可以从A&lt;sub&gt;j&lt;/sub&gt;得到的最小数字。 (见follow cmets)。
  • A&lt;sub&gt;j+1&lt;/sub&gt; 的竞争对手不仅包括我们通过删除一个数字从A&lt;sub&gt;j&lt;/sub&gt; 获得的内容,还包括通过从任何n-j 数字号码中删除一个数字获得的内容,例如A'&lt;sub&gt;j&lt;/sub&gt; ,这与A&lt;sub&gt;j&lt;/sub&gt; 不同,即我们通过删除与A&lt;sub&gt;j&lt;/sub&gt; 不同的j 数字来获得它。因此,我们还需要证明A&lt;sub&gt;j+1&lt;/sub&gt; 小于任何数字,比如A'&lt;sub&gt;j+1&lt;/sub&gt;,通过从A'&lt;sub&gt;j&lt;/sub&gt; 中删除一位数字得到,假设A&lt;sub&gt;j&lt;/sub&gt; &lt; A'&lt;sub&gt;j&lt;/sub&gt;。 (见follow cmets)
  • 例如A&lt;sub&gt;j&lt;/sub&gt;=3864 &lt; A'&lt;sub&gt;j&lt;/sub&gt;=3954,删除一位数字后,A&lt;sub&gt;j+1&lt;/sub&gt;=364 &gt; A'&lt;sub&gt;j+1&lt;/sub&gt;=354。这不是我们想要的,我们可能需要证明这种A'&lt;sub&gt;j&lt;/sub&gt;=3954 不会发生。
【解决方案2】:

这是一个简单的论点,即您的算法适用于任何 k。假设第 m 位有一个数字小于或等于它的右 (m+1) 位邻居,并且您删除了第 m 位而不是 (m+1) 位。然后你可以删除第(m+1)个数字而不是第m个,你会得到一个小于或等于你原来的答案的答案。

【讨论】:

  • 我认为这里可能对k 有一些不同的引用。您是否让k 表示参数中要删除的数字的位置。它旨在成为问题陈述中要删除的总位数,我认为@AbcAeffchen 的答案也是如此。因此,您还提出了关于删除我认为的单个数字的论点,即@AbcAeffchen 的答案中的k=1
  • @zhangwt 我滥用了 k 的符号,让它成为已删除数字的索引。现在我将索引更改为 m。该参数应该适用于任何数量 k 的已删除数字。
  • 我仍然不确定多次删除的证明,请参阅@AbcAeffchen的cmets。
【解决方案3】:

注意:这个证明是为了构建去掉k位后的最大数,但思路类似

关键引理:最大(m + 1)位数字包含最大m位 所有 m = 0, 1, ..., n - 1 的数字

证明:

  • 从某个数字中删除one 数字以获得最大值的贪婪解决方案 结果:只需删除the first digit which next digit is greater than it,或the last digit if digits are in non-ascending order。这很容易证明。

我们使用矛盾来证明引理。

  1. 假设当 m = k 时引理第一次被破坏,所以S(k) ⊄ S(k + 1)。注意S(k) ⊂ S(n)作为初始数包含所有次优数,所以必须存在x,即S(k) ⊂ S(x)S(k) ⊄ S(x - 1)k + 2 &lt;= x &lt;= n
  2. 我们使用上面的贪心解决方案从 S(x) 中只删除一个数字 S[X][y] 以获得 S(x - 1),所以 S[X][y] ∈ S(x)S[X][y] ∉ S(x - 1)S(k) 必须包含它。 We now use contradiction to prove that S(k) does not need to contain this digit .

根据我们的贪心解法,从开始到 S[X][y] 的所有数字都是 按非升序排列。

  1. 如果S[X][y] is at the tail,那么S(k) can be the first k digits of S(x) ---> 矛盾!
  2. 否则,我们首先知道S[X][1, 2,..., y] are in S[k]中的所有数字。如果有一个S[X][z] is not inS(k), 1 &lt;= z &lt;= y - 1,那么我们可以将S(k)S[X][z + 1, y]范围内的数字移动到left one unit,以获得更大或等于S(k)。因此,至少有2 数字after S[X][y]not in S(k)x &gt;= k + 2。然后,我们可以按照prefix of S(k) 到 S[X][y],但是我们使用not 使用S[X][y],我们使用来自S[X][y + 1]As S[X][y + 1] &gt; S[X][y], we can build a greater S(k) -------->矛盾!

所以,我们证明了引理。如果我们有S(m + 1),并且我们知道S(m + 1) contains S(m),那么S(m)必须是来自S(m + 1)maximum number after removing one digit

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 2022-10-01
    • 1970-01-01
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多