Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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_Performance - Fatal编程技术网

Algorithm 获取一个数字的最短可能序列

Algorithm 获取一个数字的最短可能序列,algorithm,performance,Algorithm,Performance,序列的第一个元素是1 i、 e.A[0]=1 A[i+1]可以是2A[i]或A[i]+1 我们必须找到尽可能短的序列 e、 g: If N is 18 A[0]=1, A[1]=2,4,8,9,18 所以我的代码基本上是 int count = 0; for (int i = N, i != 1;){ if (i % 2 == 0) { i /= 2; ++count; } else{ --i; ++count; } return cou

序列的第一个元素是
1

i、 e.
A[0]=1
A[i+1]
可以是
2A[i]
A[i]+1

我们必须找到尽可能短的序列

e、 g:

If N is 18
 A[0]=1, A[1]=2,4,8,9,18
所以我的代码基本上是

 int count = 0;
 for (int i = N, i != 1;){
 if (i % 2 == 0) { 
     i /= 2;
     ++count;
 } else{
     --i;
     ++count;
 }
 return count;
如您所见,该算法非常简单,将返回最短的长度。然而,最糟糕的时间复杂度是
O(N)


有没有办法使它成为O(logN)?

您的算法已经是O(logN))。要看到这一点,您的算法可以重写如下:

 int count = 0;
 for (int i = N; i != 1;) {
   if (i % 2 == 1) { 
     --i
     ++count;
   }
   i /= 2;
   ++count;
 }
 return count;
对于每一位,要么除以2,要么减去1再除以2。由于您每比特执行的操作数不取决于N的大小,因此时间是O(log(N))

关于为什么这样做的一些细节 如果你用二进制来思考。乘以2等于将位左移1。添加一是将最右边的位设置为一。因此,只要读取N的二进制值,就可以找到操作序列

N=18是二进制的10010,所以我们有

1 = starting value:            1
0 = multiply by 2 :            2
0 = multiply by 2 :            4
1 = multiply by 2 and add one: 8,9
0 = multiply by 2 :            18
这个解决方案不一定是唯一的,但它总是至少和任何其他解决方案一样短。要了解原因,您只需观察到在一行中两次添加一等于将一添加到位1并将位0调零:

xxx01 -> xxx10
但是,如果在前面添加一个,则可以得到相同的结果,因此在一行中添加两次一个没有任何好处。因此,一个最佳的操作序列包括重复乘以两次,并在每次乘法之间选择性地加一次