找工作之面试题练习2

 实现一个函数,对一个正整数n,算得到1需要的最少操作次数:
  如果n为偶数,将其处以2; 如果n为奇数,可以加1或减1;  一直处理下去。
  例子:
  ret = func(7);
  ret = 4,可以证明最少需要4次运算
  n = 7
  n—1 6
  n/2 3
  n-1 2
  n/2 1
  要求:实现函数(实现尽可能高效)
  Int func(unsign int n);n为输入,返回最小的运算次数。
  给出思路(文字描述),完成代码,并分析你算法的时间复杂度。


//第一种实现
int func2(const unsigned int n)
{
	if(1 == n)
	{
		return 0;
	}
	if(2 == n)
	{
		return 1;
	}

	if(n % 2 == 0)
	{
		return 1 + func2(n / 2);
	}
	else
	{
		int plus = func2(n + 1);
		int mines = func2(n - 1);
		return 1 + (plus < mines ? plus : mines);
	}
	return 0;
}

//第二种实现
int func3(unsigned long n)
{
	if(n == 1)
		return 0;
	if(n == 3)
		return 2;

	if(n%2 == 0)
	{
		return 1 + func3(n/2) ;
	}
		
	else
	{
		if((n+1)%4 == 0)
			return 3 + func3((n+1)/4);
		
		if((n-1)%4 == 0)
			return 3 + func3((n-1)/4);
	}

	return 0;
}


int func6(const unsigned int n)
{
	if(1 == n)
		return 0;

	if(3 == n)
		return 2;

	if(!(n & 0x01))
		return 1 + func6(n >> 1);

	else
	{

		if(!((n + 1) & 0x03))
			return 3 + func6((n + 1) >> 2);

		if(!((n - 1) & 0x03))
			return 3 + func6((n - 1) >> 2);

	}

	return 0;
}

//第三种实现
int func_iterative(unsigned int n)
{
	int step = 0;

	

	while(n != 1 && n != 3)
	{
		if( !(n & 0x01))
		{
			n >>= 1;
			++step;
		}

		else
		{
			if(!((n + 1) & 0x03))
			{
				++n;
				++step;
			}

			else if(!((n - 1) & 0x03))
			{
				--n;
				++step;
			}

		}
	}

	if(3 == n)
		step += 2;

	return step;
}





//最新添加-----实验室大牛的又一改进版本

int func(const unsigned int n)
{
    if(1 == n)
    {
        return 0;
    }
    if(3 == n)
    {
        return 2;
    }
    if(!(n & 0x01))
    {
        return 1 + func(n >> 1);
    }
    else
    {
        return 3 + (!((n + 1) & 0x03) ? func((n + 1) >> 2) : func(n >> 2));
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coffee_baba

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值