lintcode1259-Integer Replacement

题目描述:

求最小的转换次数。

这道题最初的想法就是把所有的情况都算一下,然后比较得出最小的。可以递归解决,直到N变成了1。递归想着要耗费大量时间,没想到也通过了,哈哈。

代码:

int integerReplacement(int n) {
        // Write your code here
        //普通递归思想,可以通过
        if(n <= 1)
            return 0;
        if(n==2)
            return 1;
        if(n == 3)
            return 2;
        if(n%2){
            return min(integerReplacement(n+1), integerReplacement(n-1)) + 1;
        }
        else{
            return integerReplacement(n/2) + 1;
        }
    }

既然递归的想法都能通过,那么还可以尝试进行动态规划的解法,从底向上。想法很好,但是因为申请大量的内存,会爆掉。

想法:buf[i]表示将i转成成1的最少次数。i%2==0     buf[i] = 1+buf[i/2];

                                                             i%2==1   buf[i] = min(1+buf[i-1], 2+buf[(i+1)/2])

代码:

int integerReplacement(int n){
    if(n<=1)
        return 0;
    vector<int> buf(n+1, 0);
    buf[0] = buf[1] = 0;
    buf[2] = 1;
    for(int i=3; i<=n; ++i){
        if(i%2 == 0){
            buf[i] = 1 + buf[i>>1];
        }
        else{
            buf[i] = min(1+buf[i-1] , 2+buf[(i+1)>>1]);
        }
    }
    return buf[n];
}


然后在网上看到了一种基于二进制的解法。很是巧妙,观察末尾为0,说明是偶数,直接右移一位;当末尾为1时,就要分情况讨论。目的就是把尽量多的1变成0,然后通过移位来解决。当从末尾开始,有连续两个及两个以上的1时,执行加一操作,当只是末尾是1时,执行减一操作。这当中有一个特殊情况,当N为3时,减一然后右移是最少的移动次数。

代码:

int integerReplacement(int n) {
        // Write your code here
      //利用二进制的思想
      int count = 0;
      while(n != 1){
          if((n&1) == 0){
              n >>= 1;
          }
          else if(n==3 || ((n>>1)&1)==0){
              --n;
          }
          else{
              ++n;
          }
          ++count;
      }
      return count;
    }
参考博客:https://www.jianshu.com/p/4351f30e5f07


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值