题目描述:
实现一个函数,对一个正整数n,计算得到1需要的最少操作次数。
操作规则为:如果n为偶数,将其除以2;如果n为奇数,可以加1或减1;一直处理下去。
例子:
func(7) = 4,可以证明最少需要4次运算
n = 7
n-1 6
n/2 3
n-1 2
n/2 1
要求:实现函数(实现尽可能高效) int func(unsign int n);
n为输入,返回最小的运算次数。给出思路(文字描述),完成代码,并分析你算法的时间复杂度。
分析:
关键的地方就是分析是+1?还是-1?
哪一个会减少最终的操作次数?
1)一般会想到:
int func1(unsigned int n)
{
if (n == 1)
return 0;
if (n % 2 == 0)
return 1 + func1(n / 2);
int x = func1(n + 1);
int y = func1(n - 1);
if (x > y)
return y + 1;
else
return x + 1;
}
2)要判断+1还是-1,需要考虑到最后两位(二进制情况下)
如果是*****01,那么选择减1,如果是*****11,那么选择加1,特殊情况是就是n是3的时候,选择减1操作
//recursive
int func2(unsigned int n)
{
if (n ==1)
return 0;
if (n % 2 == 0)
return 1 + func2(n / 2);
if (n == 3)
return 2;
//判断最后两位是01还是11?
if (n & 2)
return 1 + func2(n + 1);
else
return 1 + func2(n - 1);
}
//nonrecursive
int func3(unsigned int n)
{
int count = 0 ;
while (n > 1)
{
if (n % 2 == 0)
n >>= 1;
else if(n == 3)
n--;
else
{
if (n & 2)
n += 1;
else
n -= 1;
}
count++;
}
return count;
}
http://blog.csdn.net/hackbuteer1/article/details/7348968