在算法贴吧上看到的一个问题 : http://tieba.baidu.com/p/264968529
把一个正整数变为1,求最少的步数?
具体是这样的:
如果这个数是偶数,那么直接除2;
如果是奇数,加1或减1后再除2;
这样反复,一直到变为1,求最少需要几步?
例如 func(7)=4;
int func(unsigned int n);
n为输入的的正整数。
/**
* 找出一个数转成1的最小步数
* 分析奇数 2进制 如果最后一位是1 倒数第2位是0 如果这时候加1 那么就会导致除2之后要再次加1或者减1所以有可能增加步骤
* 如果倒数第2位是1 那么加1 的话 把倒数第2个也变成0 节约了倒数第2位的加减操作 当然可能会让倒数第3位要加减 但是没关系
* 这个只是相当于把倒数第2位的操作放到倒数第三位 但是如果是连续多个1就会节约步骤
*
* 但是3的话比较特殊 3虽然是11 但是减1的话会让他变成2 加1变成4多了一位
*其他的ok xx01 这个显然是 减1
* xx11 这个也是加1 因为前面还有 所以没关系
*
* @param num
* @return
*/
public static int findMinStep(int num) {
int three = 3;
int step = 0;
int tmp;
while (num > 1) {
//这个比较特殊
if (num == 3) {
step += 2;
break;
}
tmp = num & three;
if (tmp == 3) {
step += 2;
num = (num + 1) >> 1;
} else if (tmp == 1) {
step += 2;
num = (num - 1) >> 1;
} else {
step++;
num = num >> 1;
}
}
return step;
}
3的时候 比较蛋疼 差点考虑错了~ 3虽然是11 但是它的前面那个1不是必须处理的 所以加1就不合理了!
http://blog.csdn.net/mathe/article/details/1492206 看到一个证明 呵呵 跟我的思想差不多 不过它的看起来更厉害 呵呵 ~