【剑指offer系列】剑指offer 14-16

一、剑指offer 14- I. 剪绳子

题目链接:力扣

题目描述:给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0]*k[1]*...*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

示例 1:

输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1

解题思路:这道题是经典的数学问题,假设 N=n1+n2+…+nk,并且 n1×n2×…×nk 是最大乘积。

  1. 显然1不会出现在其中;
  2. 如果对于某个 i 有 ni≥5,那么把 nini 拆分成 3+(ni−3),我们有 3(ni−3)=3ni−9>ni;
  3. 如果 ni=4,拆成 2+2乘积不变,所以不妨假设没有4;
  4. 如果有三个以上的2,那么 3×3>2×2×23,所以替换成3乘积更大;

综上,选用尽量多的3,直到剩下2或者4时,用2。

时间复杂度分析:当 n 比较大时,n 会被拆分成 ⌈n/3⌉ 个数,我们需要计算这么多次减法和乘法,所以时间复杂度是 O(n)。

解题代码:

class Solution {
public:
    int cuttingRope(int n) {
        if(n<=3) return 1*(n-1);
        int res = 1;
        if(n%3==1) res=4,n-=4;
        if(n%3==2) res=2,n-=2;
        while(n){
            res*=3;
            n-=3;
        }
        return res;
    }
};

二、剑指offer 14- II. 剪绳子 II

题目链接:给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m - 1] 。请问 k[0]*k[1]*...*k[m - 1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1

解题思路:这道题和上一题一样的思路,只是把数据加强了,把res设为long long就好了。

解题代码:

class Solution {
public:
    int cuttingRope(int n) {
        if(n<=3) return 1*(n-1);
        long long res = 1;
        if(n%3==1) res=4,n-=4;
        else if(n%3==2) res=2,n-=2;
        while(n){
            res*=3;
            res%=1000000007;
            n-=3;
        }
        return res%1000000007;
    }
};

三、剑指 Offer 15. 二进制中1的个数

题目链接:力扣

题目描述:编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为 汉明重量).)。

示例 1:

输入:n = 11 (控制台输入 00000000000000000000000000001011)
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

解题思路:这题是很明显的位运算,n&1判断最后一位为1还是0,这个操作也可以用在判断奇偶上,n>>=1,把n向右移动一位。线性扫描过去,直到这个数为0。时间复杂度:O(n)

解题代码:

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int res = 0;
        while(n){
            res+=n&1;
            n>>=1;
        }
        return res;
    }
};

四、剑指 Offer 16. 数值的整数次方

题目链接:力扣

题目描述:实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。

示例 1:

输入:x = 2.00000, n = 10
输出:1024.00000

解题思路:这道题我们要看n是正数还是负数,正数的话结果是大于1的正数,负数的话结果是小于1 的负数。

解题代码:

class Solution {
public:
    double myPow(double x, int n) {
        double res=1.0;
        for(int i=n;i!=0;i/=2){
            if(i&1) res*=x;
            x*=x;
        }
        return n<0?1/res:res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_52967653/article/details/127510840