剑指offer刷题之14、15、16

剑指offer刷题之15、16

14-剪绳子

题目描述
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]xk[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
解法:
利用动态规划,
简建立一个数组,保存1-n的绳子的最大分割乘积值,则每次往后遍历的时候都先根据比该数值小的保存值的最大乘积值与该数值和那个比他小的数值之间绳子的最大分割乘积的乘积,最后的到最后的那个数值。
代码:

class Solution:
 def cutRope(self, number):
     # write code here
     if number < 2: return 0
     if number == 2:return 1
     if number == 3:return 2
     products = [0, 1, 2, 3]
     for i in range(4, number+1, 1):
         product = 0
         for j in range(1,4//2+1,1):
             res = products[j]* products[i-j]
             product = max(res,product)
             products.append(product)
     return  products[-1]

15、二进制中1的个数

题目:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
思路:
举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。直到最后变成全0.
代码:

class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0;
         while(n){
             ++count;
             n = (n - 1) & n;
         }
         return count;
     }
};

16-数值的整数次方

题目描述

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。保证base和exponent不同时为0

解法

当指数为负数的时候,可以先对指数求绝对值,然后算出次方的结果之后再取倒数。如果底数为0,则直接返回0。此时的次方在数学上是没有意义的。
除此之外,我们要注意:由于计算机表示小数(包括float和double型小数)都有误差,我们不能直接用等号(==)判断两个小数是否相等。如果两个小数的差的绝对值很小,比如小于0.0000001,就可以认为它们相等。

代码如下:

class Solution {
    /*
    由于计算机表示小数(包括float和double型小数)都有误差,我们不能直接用等号
    (==)判断两个小数是否相等。
    如果两个小数的差的绝对值很小,比如小于0.0000001,就可以认为它们相等。
    */
public:
    double Power(double base, int exponent) {
        if(equal(base,0.0)){
            return 0.0;
        }
        unsigned int absexponent=0;
        
        if(exponent<0.0){
            absexponent=(unsigned int)(-exponent);
        }else{
            absexponent=(unsigned int)(exponent);
        }
        double result=PowerWithUnsignedExponent(base,absexponent);
        if(exponent<0.0){
            result=1.0/result;
        }
        return result;
    }
    
private:
    bool equal(double num1,double num2){
        if((num1-num2)>-0.0000001&&(num1-num2)<0.0000001){
            return true;
        }
        return false;
    }
    double PowerWithUnsignedExponent(double base,unsigned int exponent){
       if(exponent==1){
           return base;
       }
        if(exponent==0){
            return 1.0;
        }
        double result=PowerWithUnsignedExponent(base,exponent>>1);
        result*=result;
        if((exponent&0x1)==1){
            result*=base;
        }
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值