【问题标题】:Concatenation of Consecutive Binary Numbers, Modulo Operation discussion behavior连续二进制数的连接,模运算讨论行为
【发布时间】:2020-12-08 01:03:09
【问题描述】:

在这里,我为这个问题贡献了 Java 解决方案。 连续二进制数的串联: 给定一个整数 n,返回将 1 到 n 的二进制表示按顺序连接形成的二进制字符串的十进制值,取模 10^9 + 7。

class Solution {
    public int concatenatedBinary(int n) {
        long sum = 0;
    
        for(int i = 1; i <= n; i++){
            sum = ((sum << Integer.toBinaryString(i).length()) + i) % 1000000007;
        }
    
        return (int) sum;
    }
}

现在我有一个疑问,那就是当我们在 for 循环中的每一步进行调制时。直到 1000000007 才会影响结果,但在那之后,它会改变 sum 变量,并且这个循环将重复。现在,为什么这个模数不会影响整体结果?提前致谢。

【问题讨论】:

  • “现在,为什么这个模数不会影响整体结果?”是什么意思?

标签: java data-structures modulo


【解决方案1】:

让我们来个更简单的问题:取数字 1000,将其写为位,然后取数字 1001,将其写为位,将两者连接起来,那是什么,十进制?

1000 in bits is 11 1110 1000
1001 in bits is 11 1110 1001

因此,答案将是 1111 1010 0011 1110 1001 或 1025001。

但是,让我们对此做一个更数学的理解:“连接两者”归结为:“将第一个数字中的位向左移动以腾出足够的空间,然后添加第二个数字”。而“左移 X”与“乘以 2X”相同。就像如果我有数字“1234”,我告诉你“将其左移 2 个点”,这与乘以 100 相同:将其变为 123400,即 1234*100,而 100 只是 10 2。因此,“左移 X 个点”与“乘以 bX”相同,其中 b 是我们使用的数字系统的“基数”;二进制 2,十进制 10。

因此,表示相同结果的另一种方式是:'取数字 1000,乘以 210,再加上 1001。果然:1000 * 2^10 + 1001确实是1025001。

因此,您的算法中的单个“循环”是有效的:将我们目前得到的结果乘以 2(X 次,其中 X 是数字中最高 1 位的位置我们正在处理这个循环),然后添加新数字。

所以,这只是乘法和加法。

模数具有对这些运算稳定的特性。

考虑基本的数学:您可能被教过有关数轴的知识。一条水平线,无限大。

模数系统没有什么不同,除了数轴是一个大循环。这是一个圆圈。在模 1000000007 空间中,数字“5 和 6”与数字“0 和 1000000006”一样相邻。

给定,在正常的数轴上,a * b = c,模具有这样的性质,这也意味着(a%Z * b%Z)%Z = c%Z 对于任何 Z。加法也是如此;如果a + b = c,那么(a%Z + b%Z)%Z = c%Z 也是如此。您可以尝试一堆数字并见证这一点,或者尝试自己证明这一点,或者在网上搜索此属性的证明。

例子:

12 * 18 = 216
(12%7 * 18%7)%7 = 216%7
Yup, that checks out:
5 * 4 = 20
20%7 = 6.
216%7 is also 6.

因此:

  1. 您的问题归结为乘法和加法的大量应用。
  2. 乘以并添加转换到模数学没有问题。
  3. 因此,您的算法有效。

【讨论】:

  • 谢谢@rzwitserloot
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-01
  • 2023-03-27
相关资源
最近更新 更多