实现一个函数,对一个正整数n,算得到1需要的最少操作次数?

本文介绍两种将任意正整数n通过除2、加1或减1操作转化为1的方法。方法一采用动态规划实现,时间复杂度为O(n)。方法二利用二进制特性进行优化,复杂度为O(log n)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://www.wenwn.com/?p=477

方法一:如果是偶数则向右移动一位,如果是奇数就判断一下+1还是-1次数少.【动态规划】

int operation1(int num) {
    int i;
	int f[num+1];
	memset(f, 0, sizeof(f));
	for( i = 2; i <= num; i++) {
		if( (i&0x1) == 0) {
			f[i] = 1+f[i>>1];
		} else {
			int a = f[(i-1)>>1]+2;
			int b = 2+ f[(i+1) >>1];
			[i] = a > b? b:a;
		}
	}
	
	return f[num];
}

时间复杂度为o(n);该算法要每个数都要算一次,然后迭代。


方法2:复杂度可以降低,我们将n转为2进制,
1 当num末尾一位为0,理所当然选择右移一位;
2 当num末尾位为1, xx101和xx001时,对于第一种情况,选择+1,-1的次数一样,对于后者则选择-1。所以对于01的情况,选择-1
3 当num末尾为11, x1011,x0011时, 对于第一种+1,-1一样。对于后者选择+1,所以对于011选择+1;
4 当num末尾为111,10111,00111时,对于第一种选择+1,对于后者选则+1,所以都选择加+1。
num>=3 选择+1

int operation2(int num)
{
	int cnt = 0;
	int tmp = num;
	while( tmp > 1) {
		if( (tmp & 0×1) == 0) {
			cnt++;tmp>>= 1;
		} else {
			if( (tmp &0×7) == 0×7) {
				cnt+=4;
				tmp +=1;
				tmp>>=3;
			} else if( (tmp &0×3 )== 0×3) {
				cnt+=2;
				tmp -=1;
				tmp >>=1;
			} else if( (tmp &0×1) == 0×1)	{
				if( tmp == 0×01) {
					return cnt;
				} else {
					cnt+=2;
					tmp -=1;
					tmp >>=1;
				}
			}
		}
	}
	return cnt;
}

这里的复杂度为num的二进制位数log2(n)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值