剑指offer 打卡计划| 每日进步一点点 | 第五天

111 阅读1分钟

图片.png

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

剑指 Offer 14- II. 剪绳子 II

思路

(数学) O(n) 这道题目是数学中一个很经典的问题,下面我们给出证明:

首先把一个正整数 N 拆分成若干正整数只有有限种拆法,所以存在最大乘积。 假设 N=n1+n2+…+nk,并且 n1×n2×…×nk是最大乘积。

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

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

时间复杂度分析

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

c++代码

 class Solution {
 public:
     int cuttingRope(int n) {
         if(n <= 3) return 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 = (res * 3)% 1000000007;
             n -= 3;
         }
         return res;
     }
 };

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

思路 (位运算)

lowbit(x) 函数的作用

lowbit(x)操作返回 x 的最后一位 1

  • x=1010_2,那么 lowbit(x) 返回 10_2,即 lowbit(x)=10
  • x=101000_2,那么 lowbit(x) 返回 1000_2,即 lowbit(x)=1000

lowbit 的应用:可以统计 x 中 1 的个数

就是每一次把 x 的最后一位 1 减掉,即 x−lowbit(x),只需要算下减多少次,减多少次就有多少个 1 。

c++代码

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

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

思路

(模拟,快速幂) O(logn)

快速幂模板:

 LL quickPow(LL a,LL b , int  mod )
 {
     LL res= 1;
     while(b)
     {
         if(b&1) res = res * a %mod;
         b >>= 1;
         a = a*a %mod;
     }
     return res;
 }

由于本题的指数是int范围,可能很大,所以需要用快速幂求解。

注意当指数是负数时,我们需要先取指数的绝对值,最后将乘积的倒数作为答案。

时间复杂度分析: 假设指数是 n,则一共会循环 O(logn) 次,所以时间复杂度是 O(logn)。

c++代码

 class Solution {
 public:
     double myPow(double x, int n) {
         typedef long long LL;
         bool is_minus = false;
         if(n < 0) is_minus = true;  //判断指数是否是负数
         LL k = abs(LL(n));  //取绝对值
         double res = 1;
         while(k){
             if(k & 1) res *= x; // k是奇数
             k >>= 1; //指数减半
             x *= x;  //底数加倍
         }
         if(is_minus) res = 1 / res;
         return res;
     }
 };