对一个正整数n,算得到1需要的最少操作次数
来源:互联网 发布:最贵域名排行 编辑:程序博客网 时间:2024/05/22 13:29
实现一个函数,对一个正整数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为输入,返回最小的运算次数。给出思路(文字描述),完成代码,并分析你算法的时间复杂度。
答:
int func(unsigned int n) { if(n == 1) return 0; if(n % 2 == 0) return 1 + func(n/2); int x = func(n + 1); int y = func(n - 1); if(x > y) return y+1; else return x+1; }
假设n表示成二进制有x bit,可以看出计算复杂度为O(2^x),也就是O(n)。
将n转换到二进制空间来看(比如7为111,6为110):
- 如果最后一位是0,则对应于偶数,直接进行除2操作。
- 如果最后一位是1,情况则有些复杂。
**如果最后几位是???01,则有可能为???001,???1111101。在第一种情况下,显然应该-1;在第二种情况下-1和+1最终需要的步数相同。所以在???01的情况下,应该选择-1操作。
**如果最后几位是???011,则有可能为???0011,???11111011。在第一种情况下,+1和-1最终需要的步数相同;在第二种情况下+1步数更少些。所以在???011的情况下,应该选择+1操作。
**如果最后有更多的连续1,也应该选择+1操作。
如果最后剩下的各位都是1,则有11时应该选择-1;111时+1和-1相同;1111时应选择+1;大于四个1时也应该选择+1;
int func(unsigned int n) { if(n == 1) return 0; if(n % 2 == 0) return 1 + func(n/2); if(n == 3) return 2; if(n&2) return 1 + func(n+1); else return 1 + func(n-1); }
由以上的分析可知,奇数的时候加1或减1,完全取决于二进制的后两位,如果后两位是10、00那么肯定是偶数,选择除以2,如果后两位是01、11,那么选择结果会不一样的,如果是*****01,那么选择减1,如果是*****11,那么选择加1,特殊情况是就是n是3的时候,选择减1操作。
非递归代码如下:
// 非递归写法 int func(int n) { int count = 0; while(n > 1) { if(n % 2 == 0) n >>= 1; else if(n == 3) n--; else { if(n&2) // 二进制是******11时 n++; else // 二进制是******01时 n--; } count++; } return count; }
另外一种写法如下:
// 非递归写法 int func(int n) { int count = 0; while(n > 1) { if(n % 2 == 0) // n % 4等于0或2 n >>= 1; else if(n == 3) n--; else n += (n % 4 - 2); // n % 4等于1或3 count++; } return count; }
- 实现一个函数,对一个正整数n,算得到1需要的最少操作次数?
- 实现一个函数,对一个正整数n,算得到1需要的最少操作次数?
- 实现一个函数,对一个正整数n,算得到1需要的最少操作次数:
- 实现一个函数,对一个正整数n,算得到1需要的最少操作次数?
- 对一个正整数n,算得到1需要的最少操作次数。
- 对一个正整数n,算得到1需要的最少操作次数
- 算得到1需要的最少操作次数
- 算得到1需要的最少操作次数
- 1、对一个正整数算到1需要的最少操作次数
- 实现一个函数,对一个正整数n,算得到1
- 正整数n到1的最少操作次数_Glodon(6)_20160923
- 1到n的正整数x出现的次数
- 本题要求实现一个函数,对给定的正整数N,打印从1到N的全部正整数。
- 给一个正整数 n, 找到若干个完全平方数(比如1, 4, 9, ... )使得他们的和等于 n。你需要让平方数的个数最少。
- 给一个正整数 n, 找到若干个完全平方数(比如1, 4, 9, ... )使得他们的和等于 n。你需要让平方数的个数最少。
- 求从N到1的最少操作次数(仅允许加减1或除2)
- n从1开始,每个操作可以选择对n加1或者对n加倍,想获取的2016,最少需要多少个操作。
- 比如你给它任意一个正整数,它可以按照一定的运算规则, 计算出得到1的最少操作次数。
- Android一般开发的时候的屏幕适配是怎么做的
- CSS3之盒模型阴影
- SpringMVC验证框架Validation特殊用法
- Java语言基础新手熟知
- linux常用命令-part3
- 对一个正整数n,算得到1需要的最少操作次数
- python线程池(threadpool)模块使用
- animation中的transform
- zoj3872Beauty of Array
- POJ-3071 Football (概率DP)
- python-模拟math.pi
- leetcode:25. Reverse Nodes in k-Group
- linux常用命令-part1
- case when 将表中一列按照一定规则分两列显示