返回顶部
首页 > 资讯 > 后端开发 > Python >Java实现快速幂算法详解
  • 528
分享到

Java实现快速幂算法详解

Java实现快速幂算法Java快速幂算法Java快速幂 2022-11-13 18:11:47 528人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录前言1. 暴力算法(fail)2. 优化取模运算(accept)3. 优化时间复杂度(accept)4. 优化 位运算(accept)前言 此算法偶尔会出现在笔试以及面试中,特意

前言

此算法偶尔会出现在笔试以及面试中,特意花时间研究了下这题

题目:

求AB次方,并且保留最后几位数字(此题保留最后3位数)

例子:

21000,输出的结果保留3位数字

在笔试或者面试中看到此题,第一思路可能通过递归或者while遍历的想法,但细想一下,这么大的数字编程语言中任何一个变量或者计算机硬件机器也hold不住这么大的数字存储(越往后幂次越大,总是会溢出)

此时想到了海量数据如何存储:海量数据处理的高频面试题分析

那我就选择布隆过滤器:布隆过滤器的原理和实现详细分析(全)。(但可能会有误差)

硬件无法存储,那我就分片切片,甚至二进制移位来对应计算(但是我是21000次方,每一次的幂算,我都整这么复杂,这计算一个数字要花大半天??)

冷静思考后,我发现想复杂了,应该从数学推导公式下手,才能提高算法的优化

以下章节对应算法复杂度的优化

1. 暴力算法(fail)

算法如下:


public long slowPower(long base,long power){
    long result = 1;
    
    // 依次通过for循环,将其对应的数字乘
    for(int i = 1 ;i <= power;i++){
        result *= base;
    }
    
    // 保留最后的3位数字,求余1000
    return result % 1000;
}

或者使用while循环

public long slowPower(long base,long power){
    long result = 1;
    
    while(power--){
        result *= base;
    }
    return result % 1000;
}

此处的代码执行的时候,就会出现数组越界

幂次运算,越到最后,爆炸式的增长:

对此求余是最好的想法(因为数值很大保留最后几位即可)

但数值本身就已经越界,而且爆炸增长也算不到最后的数值,更不用提及求余

2. 优化取模运算(accept)

从上面的理论可得知,在求到某一步的时候,数值已经越界,那可以提前求余在计算么

那就要从取模运算进行深入了解:取模运算百度百科

本身模运算与基本四则运算相似

  • (a + b) % p = (a % p + b % p) % p
  • (a - b) % p = (a % p - b % p ) % p
  • (a * b) % p = (a % p * b % p) % p
  • a ^ b % p = ((a % p)^b) % p

其他的重要的也可提前过一遍(哪天用得上)

结合律:

  • ((a+b) % p + c) % p = (a + (b+c) % p) % p
  • ((ab) % p * c)% p = (a * (bc) % p) % p

分配律:

  • (a+b) % p = ( a % p + b % p ) %p
  • ((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p

特别是这个公式:(a * b) % p = (a % p * b % p) % p

算法如下:


public long fastPower(long base,long power){
    long result = 1;
    
    // 依次通过for循环,将其对应的数字乘
    for(int i = 1 ;i <= power;i++){
        result *= base;
        result %= 1000;
    }
    
    // 保留最后的3位数字,求余1000
    return result % 1000;
}

3. 优化时间复杂度(accept)

上面的计算是21000,如果是210000000000000000000000000000那时间复杂度随着指数的增加而增加,而且迭代的次数也特别多,那优化时间复杂度么?

通过幂次的巧妙处理,将其幂次计算的迭代减少

具体如下:(计算210

pow(2,10)
= pow(4,5)
= pow(4,4) * pow(4,1)
= pow(16,2) * pow(4,1)
= pow(256,1) * pow(4,1)

  • 幂次为偶数,直接处理
  • 幂次为奇数,拆1 以及 偶数

知道所有的指数都变为1,将其相乘即为最终的结果

最终的算法:


public long fasterPower(long base,long power){
    long result = 1;
    
    // 保证指数大于0 遍历
    while (power > 0) {
    
        // 偶数
        if (power % 2 == 0) {
            // 指数减半
            power /= 2;
            // 底数平方,记得 (模的运算优化)
            base = base * base % 1000;
            
        } else {
            // 指数为奇数
            // 拆分为1 和 偶数
            power -= 1;
            
            // result乘底数 求余 并且放在result(提前存储)
            result = result * base % 1000;
            
            // power偶数,再操作一次
            // 底数平方,记得 (模的运算优化)
            power /= 2;
            base = base * base % 1000;
        }
    }
    
    // 直接输出结果,已经不用求余了
    return result;
}

通过上面的算法发现冗余复杂了,提取公共部分合并


public long fasterPower(long base,long power){
    long result = 1;
    
    // 保证指数大于0 遍历
    while (power != 0) {
    
        // 奇数特殊判断
        if (power % 2) {
            result = result * base % 1000;
        } 
       
        // 再次操作一次,底数平方,记得 (模的运算优化)
        // 此处之所以不用减1,是因为 power 会向下取整 ,5 / 2 = 2 
        power /= 2;
        base = base * base % 1000;
     
    }
    
    // 直接输出结果,已经不用求余了
    return result;
}

4. 优化 位运算(accept)

除2(右移),可以使用移位来计算

// 非递归
public long fastestPower(long base,long power){
    long result = 1;
    
    while (power != 0) {
    
        // 奇数特殊判断
        if (power & 1) {
            result = result * base % 1000;
        } 
       
        power >>= 1;
        base = base * base % 1000;
     
    }
    
    // 直接输出结果,已经不用求余了
    return result;
}

通过上面的层层递进进行优化,自然也可用递归

// 递归
public long fastestPower(long base,long power){
    if(power == 0) {
        return 1;
    }
    
    return fastestPower(base * base, power >> 1) * (power & 1 == 1 ? base : 1);
}

以上就是Java实现快速幂算法详解的详细内容,更多关于Java快速幂算法的资料请关注编程网其它相关文章!

--结束END--

本文标题: Java实现快速幂算法详解

本文链接: https://lsjlt.com/news/169370.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java实现快速幂算法详解
    目录前言1. 暴力算法(fail)2. 优化取模运算(accept)3. 优化时间复杂度(accept)4. 优化 位运算(accept)前言 此算法偶尔会出现在笔试以及面试中,特意...
    99+
    2022-11-13
    Java实现快速幂算法 Java快速幂算法 Java快速幂
  • Java语言实现快速幂取模算法详解
    快速幂取模算法的引入是从大数的小数取模的朴素算法的局限性所提出的,在朴素的方法中我们计算一个数比如5^1003%31是非常消耗我们的计算资源的,在整个计算过程中最麻烦的就是我们的5^1003这个过程缺点1:在我们在之后计算指数的过程中,计算...
    99+
    2023-05-30
    java 快速幂取模 算法
  • Golang实现快速求幂的方法详解
    今天讲个有趣的算法:如何快速求nm,其中n和m都是整数。 为方便起见,此处假设m>=0,对于m< 0的情况,求出n|m|后再取倒数即可。 另外此处暂不考虑结果越界的情况(...
    99+
    2024-04-02
  • Java数据结构之快速幂的实现
    目录引入具体方法代码实现题目矩阵快速幂斐波那契数列第 N 个泰波那契数统计元音字母序列的数目引入 快速幂是用来解决求幂运算的高效方式。 例如我们要求 x 的&nb...
    99+
    2024-04-02
  • c++入门必学算法之快速幂思想及实现
    目录一、什么是快速幂二、快速幂思想及实现总结一、什么是快速幂 快速幂算法是用来快速计算指数表达式的值的,例如 210000000,普通的计算方法 2*2*2*2…乘10...
    99+
    2022-11-13
    C++快速幂算法 c++ 快速幂 c++幂运算
  • Golang怎么实现快速求幂
    这篇文章主要介绍了Golang怎么实现快速求幂的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang怎么实现快速求幂文章都会有所收获,下面我们一起来看看吧。为方便起见,此处假设m>=0,对于m<...
    99+
    2023-07-02
  • 详解Java双轴快速排序算法
    目录一、前言二、回顾单轴快排三、双轴快排分析3.1、总体情况分析3.2、k交换过程3.3、收尾工作四、双轴快排代码一、前言 首选,双轴快排也是一种快排的优化方案,在JDK的Array...
    99+
    2024-04-02
  • java如何实现快速排序算法
    这篇文章将为大家详细讲解有关java如何实现快速排序算法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。快速排序算法使用的分治法策略来把一个序列分为两个子序列来实现排序的思路:1.从数列中挑出一个元素,称为...
    99+
    2023-06-02
  • 图文详解JAVA实现快速排序
    高快省的排序算法 有没有既不浪费空间又可以快一点的排序算法呢?那就是“快速排序”啦!光听这个名字是不是就觉得很高端呢。 假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个...
    99+
    2024-04-02
  • java实现快速排序图文详解
    目录高快省的排序算法排序算法显神威总结高快省的排序算法 有没有既不浪费空间又可以快一点的排序算法呢?那就是“快速排序”啦!光听这个名字是不是就觉得很高端呢。 假设我们现在对“6 1 ...
    99+
    2024-04-02
  • 超详细解析C++实现快速排序算法的方法
    目录一、前言1.分治算法2.分治算法解题方法二、快速排序1.问题分析2.算法设计3.算法分析三、AC代码一、前言 1.分治算法 快速排序,其实是一种分治算法,那么在了解快速排序之前,...
    99+
    2024-04-02
  • JAVA十大排序算法之快速排序详解
    目录快速排序问题思路荷兰国旗问题代码实现时间复杂度算法稳定性总结快速排序 快速排序是对冒泡排序的一种改进,也是采用分治法的一个典型的应用。JDK中Arrays的sort()方法,具体...
    99+
    2024-04-02
  • C#实现快速排序算法
    快速排序是应用最广泛的排序算法,流行的原因是它实现简单,适用于各种不同情况的输入数据且在一般情况下比其他排序都快得多。 快速排序是原地排序(只需要一个很小的辅助栈),将长度为 N 的...
    99+
    2024-04-02
  • java数据结构与算法之快速排序详解
    本文实例讲述了java数据结构与算法之快速排序。分享给大家供大家参考,具体如下:交换类排序的另一个方法,即快速排序。快速排序:改变了冒泡排序中一次交换仅能消除一个逆序的局限性,是冒泡排序的一种改进;实现了一次交换可消除多个逆序。通过一趟排序...
    99+
    2023-05-31
    java 数据结构 算法
  • 图解Java经典算法快速排序的原理与实现
    目录快速排序算法原理图解Java代码实现算法分析快速排序 通过一趟排序将待排元素分成独立的两部分,其中一部分为比基准数小的元素,另一部分则是比基准数大的元素。然后对这两部分元素再按照...
    99+
    2024-04-02
  • FlutterDart快速排序算法示例详解
    目录引言快速排序算法分治法(Divide and conquer)快速排序算法实现引言 在日常研发的过程中,我们无时无刻都在考虑自己开发的程序是否高效,一段好的程序执行离不开对算...
    99+
    2022-12-09
    Flutter Dart快速排序算法 Flutter Dart算法
  • 详解Python排序算法的实现(冒泡,选择,插入,快速)
    目录1. 前言2. 冒泡排序算法2.1 摆擂台法2.2 相邻两个数字相比较3. 选择排序算法4. 插入排序5. 快速排序6. 总结1. 前言 所谓排序,就是把一个数据群体按个体数据的...
    99+
    2024-04-02
  • Python实现求解斐波那契第n项的解法(包括矩阵乘法+快速幂)
    斐波那契数列 首先我们来定义一下斐波那契数列: 即数列的第0项: 算法一:递归 递归计算的节点个数是O(2ⁿ)的级别的,效率很低,存在大量的重复计算。 比如: f(...
    99+
    2024-04-02
  • 详解Java实现分治算法
    目录一、前言二、分治算法介绍三、分治算法经典问题3.1、二分搜索3.2、快速排序3.3、归并排序(逆序数)3.4、最大子序列和3.5、最近点对四、结语一、前言 在学习分治算法之前,问...
    99+
    2024-04-02
  • 在Java中怎么实现一个快速排序算法
    在Java中怎么实现一个快速排序算法?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序...
    99+
    2023-05-30
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作