【发布时间】:2016-09-02 23:54:15
【问题描述】:
问题陈述如下:
给定一个数x,找出大于或等于x的最小稀疏数 如果一个数字在其二进制表示中没有两个相邻的 1,则该数字是稀疏的。例如 5(二进制表示:101)是稀疏的,但 6(二进制表示:110)不是稀疏的。
我从this post 提出问题,其中最有效的解决方案被列为运行时间为 O(logn):
1) 找到给定数字的二进制并将其存储在 布尔数组。 2) 将 last_finalized 位位置初始化为 0。 2) 从最低有效位开始遍历二进制。 a)如果我们得到两个相邻的 1 使得下一个(或第三个) 位不为 1,则 (i) 使这个 1 之后的所有位最后最终确定 位(包括最后确定的)为 0。 (ii) 将最后确定的位更新为下一位。
帖子中不清楚的是“最终确定的位”是什么意思。似乎该算法首先使用 while 循环将数字的二进制表示插入到 std::vector 中,在该循环中,它将输入(即数字 x)与 1 进行与运算,然后将其推回向量中,但是,在至少从提供的描述来看,尚不清楚为什么要这样做。 对于这个问题的有效解决方案有更清晰的解释(甚至方法)吗?
编辑:
// Start from second bit (next to LSB)
for (int i=1; i<n-1; i++)
{
// If current bit and its previous bit are 1, but next
// bit is not 1.
if (bin[i] == 1 && bin[i-1] == 1 && bin[i+1] != 1)
{
// Make the next bit 1
bin[i+1] = 1;
// Make all bits before current bit as 0 to make
// sure that we get the smallest next number
for (int j=i; j>=last_final; j--)
bin[j] = 0;
// Store position of the bit set so that this bit
// and bits before it are not changed next time.
last_final = i+1;
}
}
【问题讨论】:
-
尝试在纸上手动执行算法,看看它是如何运作的。
-
"finalized" 在这种情况下意味着您已经计算了它的最终值。所以“最终位”是您知道其最终值的最后一位的位置。这意味着您可以在算法的下一次迭代中从那里开始,因为之前的位不会改变。
-
该解释省略了算法的一个重要部分,即在第 2.a 部分下的某处将下一位设置为 1。
标签: algorithm bit-manipulation