栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

剑指offer 14-II. 剪绳子 II(大数求余问题)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

剑指offer 14-II. 剪绳子 II(大数求余问题)

剑指 Offer 14- II. 剪绳子 II - 力扣(LeetCode) (leetcode-cn.com)

本题只是在 "剪绳子 I" 的基础上增大了数据,因此我们只需要另外处理大数求余问题即可。

剪绳子I的题解:

剑指offer 14 - I. 剪绳子(贪心,DP)_Corux的博客-CSDN博客

目录

分析

代码

运行结果


分析

处理一般性的大数求余问题的方法。

pow(a,x) % N

N是一个不超过32位的int型数据,a小于N, 当x较大时,pow(a,x)很可能超过64位,无法整型来表示。

我们希望在求解pow(a, x)的过程中,一旦发现结果超过了N,便令结果mod N。

a的多少次幂刚好超过N呢?

设
pow(a, k-1) <= N < pow(a, k)
则
k = log(N) / log(a) + 1

 那么也就是说对于pow(a, y),当y < k时,pow(a, y) <= N,此时不需要模运算;当y达到k时,pow(a, y)刚刚超过N,此时进行模运算即可。

因为x可写成以下形式:
x = p * k + q    ( 0 <= q <= k-1 )

所以:pow(a, x) = pow(pow(a, k), p) * pow(a, q)

因此 

pow(a, x) % N = pow( pow(a, k)%N, p ) * pow(a, q) % N

注意到pow(a, k)%N 和 pow(a, x)%N具有同样的形式,因此对其进行递归求解即可。

代码
class Solution {
    int N = 1000000007;
public:
    int cuttingRope(int n) {
        if (n == 2) return 1;       //处理两个特殊情况
        else if (n == 3) return 2;

        int x = n / 3, r = n % 3;
        if (!r) return R(3, x, N);
        else if (r & 1) return R(3, x - 1, N) * 4 % N;
        else return R(3, x, N) * 2 % N;
    }

    int64_t R(int a, int x, int N) {    //求pow(a, x) % N的函数
        if (!x) return 1;
        int k = log(N) / log(a) + 1;
        int p = x / k, q = x % k;
        return R(power(a, k) % N, p, N) * power(a, q) % N;
    }

    int64_t power(int a, int x) {   //自己写的pow函数,因为标准库pow函数返回的是double类型,转化成整型会丢失精度,在数值较大时表现的尤为明显
        if (!x) return 1;
        int64_t res = 1;
        while (x--) res *= a;
        return res;
    }
};

运行结果

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/841114.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号