50. Pow(x, n)快速幂算法

实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即,xn )。此函数应将 x 作为浮点数(意味着它可以是十进制数)和 n 作为整数(可以是正数、负数或零)一起使用。

快速幂(Exponentiation by Squaring) 的时间复杂度是 O(log n),而不是 O(n)。因此比普通连续相乘的暴力解法快很多,尤其在指数很大时更为明显。

快速幂利用了指数的 二进制分解。关键在于每次指数都除以 2(右移)。

代码:

class Solution {public double myPow(double x, int n) {// If power n is non-negative, calculate power using helper method// 如果指数 n 是非负数,直接调用辅助方法计算if (n >= 0) {return quickPow(x, n);} else {// If power n is negative, calculate the inverse of the power// 如果指数 n 是负数,先转成 long 类型防止溢出,然后计算倒数return 1 / quickPow(x, -(long) n);}}private double quickPow(double base, long exponent) {double result = 1; // Initialize result to neutral element for multiplication// 初始化结果为 1(乘法的单位元)// Loop through all bits of the exponent// 遍历指数的每一位(二进制)while (exponent > 0) {// If the current bit is set, multiply the result by the base// 如果当前位是 1(即指数是奇数),说明该位有效,就把当前 base 乘进结果中if ((exponent & 1) == 1) {result *= base;}// Square the base for the next bit in the exponent// 每处理一位,把 base 平方,指数除以 2,平方乘法base *= base;// Shift exponent to the right to process the next bit// 指数右移一位,继续处理下一个最低位exponent >>= 1;}// Return the final result of base raised to the exponent// 返回最终结果return result;}
}

平方乘法的数学原理

我们知道:

  • x² = x * x

  • x⁴ = (x²)²

  • x⁸ = (x⁴)²

也就是说:

x^2k = (x^k)^2

这说明:

如果我们每次把底数平方,就相当于一次性“处理了两个幂”。

⛳ 示例过程:a = 2, n = 13

nn 的二进制当前位result 操作base 操作新 result新 base
1311011result *= basebase = base²24
601100-base = base²216
300111result *= basebase = base²32256
100011result *= basebase = base²819265536
00000-结束

如果指数 n 是负数,先转成 long 类型防止溢出 

Java 中 int 类型的取值范围是:
👉 [-2³¹, 2³¹ - 1]
👉 即 [-2147483648, 2147483647]

int n = Integer.MIN_VALUE;   // n = -2147483648
int positive = -n;           // 正常来说你想让它变成 2147483648

System.out.println(positive); // 实际输出:-2147483648(依然是负数!)
为什么?因为 2147483648 超出了 int 最大值!

✅ 解决方法:先转成 long
return 1 / quickPow(x, -(long) n);
这样 -(long) n 的计算就不会发生溢出了:

long 是 64 位的,能表示的范围非常大:

-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807

int 的表示范围大得多,所以:

long n = Integer.MIN_VALUE; // n = -2147483648 long positive = -n; // 不会溢出 System.out.println(positive); // 输出:2147483648 ✅

🔍 为什么这在快速幂中很重要?
因为我们要把 n 转为正数,才能做快速幂:

如果你不转为 long,那么:
quickPow(x, -n); // 这里 -n 就可能等于 Integer.MIN_VALUE
就会导致逻辑错误甚至死循环(因为指数没变正)。

📘 看一下几个重要值及其补码:

十进制值二进制补码表示注释说明
-214748364810000000 00000000 00000000 00000000最小的 int,符号位为 1,其他全 0
-214748364710000000 00000000 00000000 00000001第二小,最低位是 1
-111111111 11111111 11111111 11111111补码中所有位都是 1
000000000 00000000 00000000 00000000全 0
100000000 00000000 00000000 00000001正数,从 1 开始递增
214748364701111111 11111111 11111111 11111111int 能表示的最大值

补码的优点:正负数加法可以统一处理(硬件电路简单)

为什么溢出会“绕回原值”?

Java 中的 int 是固定长度的 32 位,有符号整数。
当你进行超出范围的计算时,多出来的部分会被截断,留下的低 32 位成为新的值。
这就像一个指针在一个圆圈里走路,走过最大值后,就绕到了最小值。

为什么右移?

因为在快速幂算法中,我们是从低位(最右边)开始处理二进制位的,所以需要不断右移指数,把最低位移出去,这样我们就能一位一位检查该不该乘上当前的 base

  • 右移一位(>> 1):相当于除以 2 向下取整

  • 左移一位(<< 1):相当于乘以 2

我们在快速幂中需要不断除以 2,是为了把 exponent 处理完(直到它变成 0)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88403.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88403.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打造丝滑的Android应用:LiveData完全教程

为什么你需要LiveData&#xff1f; 在Android开发中&#xff0c;数据的动态更新一直是个让人头疼的问题。想象一下&#xff1a;你的界面需要实时显示用户的余额变化&#xff0c;或者一个聊天应用的未读消息数得随时刷新。过去&#xff0c;我们可能会用Handler、手动监听器&…

vue3 el-table 根据字段值 改变整行字体颜色

在 Vue 3 中使用 Element Plus 的 el-table 组件时&#xff0c;如果你想根据某一列的字段值来改变整行的字体颜色&#xff0c;你可以通过使用自定义的 row-class-name 属性或者通过插槽&#xff08;slot&#xff09;的方式来达到目的。以下是两种常见的方法&#xff1a; 方法一…

Linux的全新网络管理命令行工具——nmcli

一、nmcli简介 1.1、NetworkManager简介 1.1.1、NetworkManager介绍 在红帽系的Linux中&#xff0c;默认的网络服务是由NetworkManager提供的&#xff08;其主要是一个可以进行动态网络配置和控制的守护进程&#xff09;。 使用NetworkManager的优点 序号使用NetworkManager的优…

C++基础之智能指针

一、概念 堆内存对象需要手动使用delete销毁&#xff0c;如果没有使用delete销毁就会造成内存泄漏。 所以C在ISO98标准中引入了智能指针的概念&#xff0c;并在ISO11中趋于完善。 使用智能指针可以让堆内存对象具有栈内存对象的特点&#xff0c;原理是给需要手动回收的内内存对…

python3虚拟机线程切换过程

python实现了自己的多线程&#xff0c;为了保证线程安全&#xff0c;引入了全局解释器锁GIL&#xff0c;只有拿到GIL的线程才能执行&#xff0c;所以在python中同一时刻只能有一个线程在运行&#xff0c;python多线程无法发挥多核处理器的威力&#xff0c;《python源码剖析》中…

PYTHON从入门到实践5-列表操作

# 【1】列表是可变的&#xff0c;可以修改、追加、删除 import randomclass Friend(object):def __init__(self, name, age):self.name nameself.age ageif __name__ __main__:friendList []for i in range(0, 9):randomNumber random.randint(0, 100)friend Friend(f&qu…

【linux】network服务启动网卡流程

目录 1、介绍2、ifup流程【1】与NetworkManager兼容【2】ifup-eth设置ip【3】ifup-routes设置路由 1、介绍 network服务的核心由/etc/sysconfig/network-scripts/下一堆脚本配置来生效&#xff0c;其中启动网卡就是通过ifup脚本来实现的&#xff0c;下面就讲一下ifup如何恢复i…

如何防止自己的电脑被控制?开启二次验证保护教程

远程操作什么最重要&#xff1f;安全&#xff0c;安全&#xff0c;和安全&#xff01;答案永远是安全&#xff01;那么究竟如何能让远程连接安全性更上一层台阶呐&#xff1f;又是哪家远控安全策略方面最给力呐&#xff1f;这可不是王婆卖瓜&#xff0c;自卖自夸&#xff0c;确…

微信小程序节点相关总结

微信小程序节点事件总结 bindtap、catchtap、bindclick的区别&#xff1f;bindclick 和 bindtap 的区别在于&#xff1a; e.target和e.currentTargete.typee.timeStamp触摸事件属性&#xff08;针对触摸类事件&#xff09;坐标信息事件绑定数据冒泡与捕获相关其他特殊属性**常见…

XSD是什么,与XML关系

XSD&#xff08;XML Schema Definition&#xff09;是用于描述XML文档结构和内容的一种规范。它定义了XML文档中元素、属性、数据类型、数据格式以及它们之间的关系和约束。XSD是W3C&#xff08;万维网联盟&#xff09;推荐的标准之一&#xff0c;它比早期的DTD&#xff08;Doc…

Ubuntu服务器中MySQL如何进行主从复制

一、MySQL 主从复制基本原理 MySQL 主从复制是指&#xff1a;一台数据库服务器负责写入操作&#xff0c;并将数据变更以二进制日志形式记录下来;一台或多台从库通过读取主库的二进制日志&#xff0c;实时或半实时地将主库的写入操作同步到自身数据库&#xff0c;实现数据一致性…

Android图形系统框架解析

前言 Android图形系统对于开发者来说可能会比较难以理解&#xff0c;因为涉及的东西可能会计较多&#xff0c;比如Android自己的图形系统。OpenGL&#xff0c;视频编解码器&#xff0c;SurfaceFlinger&#xff0c;FrameBuffer等等。下面我们结合官方文档&#xff0c;介绍一下图…

AI智能巡检系统给烘焙店开的「减损药方」 InfiSight智睿视界

01 食材浪费&#xff1a;甜蜜产业的苦涩成本 后厨操作台上&#xff0c;刚过最佳赏味期的可颂成批倒入垃圾桶——这是烘焙店最隐秘的痛。现烤现售模式虽保障新鲜度&#xff0c;却让原料管理沦为盲区&#xff1a; 销售数据≠生产指南&#xff1a;总部无法感知门店实时库存 …

工具 | vscode 发出声音,如何关闭

设置->搜 accessibility -> Accessibility Support -> 自动 改为 off 设置->搜 volume -> 0 设置->搜 sound -> 辅助功能信号 -> sound的 自动 改为 off 参考&#xff1a; How to turn off (or on) sounds from Visual Studio Code? - Stack Ove…

Hyperf 数据库事务指南(PHP 框架)

Hyperf 数据库事务指南&#xff08;PHP 框架&#xff09; 1. ⚙️ 数据库配置 1.1 配置文件 MySQL 配置位于 config/database.php&#xff0c;通常通过环境变量&#xff08;.env&#xff09;管理敏感信息&#xff1a; <?phpdeclare(strict_types 1); /*** This file i…

动态ds-vnp之normal和shortcut两种方式配置案例

normal方式配置 hub配置 dhcp enable interface GigabitEthernet0/0/0 ip address 3.3.3.3 255.255.255.0 interface GigabitEthernet0/0/1 ip address 192.168.3.254 255.255.255.0 dhcp select interface interface Tunnel0/0/0 ip address 10.1.1.3 255.255.255.0 tunnel…

ubuntu20.04调试livox aiva驱动获取激光雷达数据

实验环境ubuntu20.04 平台包括本地x86平台和jetson orin平台都测试ok 参考 ubuntu20.04上获取Livox Avia雷达点云数据 1.下载相关资料 下载包括&#xff1a;Livox Avia 用户手册中文.pdf、Livox_Viewer_For_Linux_Ubuntu16.04_x64_0.10.0&#xff08;用于显示激光雷达数据&am…

VS2022 C#【自动化文件上传】AutoFileUpload 新需求 V13

这里写自定义目录标题 需求分析实现方法原来&#xff08;需要修改的位置&#xff09;替换为如下代码&#xff08;添加三行数据&#xff09; 需求 现在已有程序&#xff1a;AutoFileUpload 存储excel表中时间列的第一列的列名到数据库中 分析 user只是想存储列名到数据表列去…

技术QA | ADC/DAC芯片测试研讨会笔记请查收!

6月19日&#xff0c;《ADC/DAC芯片测试前沿&#xff1a;德思特ATX系统高效方案与实战攻略》线上研讨会圆满结束。感谢大家的观看与支持&#xff01; 在直播间收到一些观众的技术问题&#xff0c;我们汇总了热点问题并请讲师详细解答&#xff0c;在此整理分享给大家&#xff0c…

区块链技术未来的发展趋势

以下是区块链技术未来的一些发展趋势&#xff1a; 技术层面 - 性能提升&#xff1a;分片技术会不断成熟和完善&#xff0c;将区块链网络划分为多个分片&#xff0c;每个分片独立处理交易&#xff0c;以提高交易吞吐量和网络可扩展性。同时&#xff0c;共识机制也会持续创新&a…