|
42 | 42 |
|
43 | 43 | ## 解法
|
44 | 44 |
|
| 45 | +<!-- 这里可写通用的实现逻辑 --> |
| 46 | + |
| 47 | +**方法一:数学(快速幂)** |
| 48 | + |
| 49 | +快速幂算法的核心思想是将幂指数 $n$ 拆分为若干个二进制位上的 $1$ 的和,然后将 $x$ 的 $n$ 次幂转化为 $x$ 的若干个幂的乘积。 |
| 50 | + |
| 51 | +时间复杂度 $O(\log n)$,空间复杂度 $O(1)$。其中 $n$ 为幂指数。 |
| 52 | + |
45 | 53 | <!-- tabs:start -->
|
46 | 54 |
|
47 | 55 | ### **Python3**
|
48 | 56 |
|
| 57 | +<!-- 这里可写当前语言的特殊实现逻辑 --> |
| 58 | + |
49 | 59 | ```python
|
50 | 60 | class Solution:
|
51 | 61 | def myPow(self, x: float, n: int) -> float:
|
52 |
| - if n == 0: |
53 |
| - return 1 |
54 |
| - if n == 1: |
55 |
| - return x |
56 |
| - if n == -1: |
57 |
| - return 1 / x |
58 |
| - half = self.myPow(x, n // 2) |
59 |
| - return half * half * self.myPow(x, n % 2) |
| 62 | + def qmi(a, k): |
| 63 | + res = 1 |
| 64 | + while k: |
| 65 | + if k & 1: |
| 66 | + res *= a |
| 67 | + a *= a |
| 68 | + k >>= 1 |
| 69 | + return res |
| 70 | + |
| 71 | + return qmi(x, n) if n >= 0 else 1 / qmi(x, -n) |
60 | 72 | ```
|
61 | 73 |
|
62 | 74 | ### **Java**
|
63 | 75 |
|
| 76 | +<!-- 这里可写当前语言的特殊实现逻辑 --> |
| 77 | + |
64 | 78 | ```java
|
65 | 79 | class Solution {
|
66 | 80 | public double myPow(double x, int n) {
|
67 |
| - if (n == 0) return 1; |
68 |
| - if (n == 1) return x; |
69 |
| - if (n == -1) return 1 / x; |
70 |
| - double half = myPow(x, n / 2); |
71 |
| - return half * half * myPow(x, n % 2); |
| 81 | + long N = n; |
| 82 | + return n >= 0 ? qmi(x, N) : 1.0 / qmi(x, -N); |
| 83 | + } |
| 84 | + |
| 85 | + private double qmi(double a, long k) { |
| 86 | + double res = 1; |
| 87 | + while (k != 0) { |
| 88 | + if ((k & 1) != 0) { |
| 89 | + res *= a; |
| 90 | + } |
| 91 | + a *= a; |
| 92 | + k >>= 1; |
| 93 | + } |
| 94 | + return res; |
72 | 95 | }
|
73 | 96 | }
|
74 | 97 | ```
|
75 | 98 |
|
76 |
| -### **JavaScript** |
| 99 | +### **C++** |
77 | 100 |
|
78 |
| -```js |
79 |
| -/** |
80 |
| - * @param {number} x |
81 |
| - * @param {number} n |
82 |
| - * @return {number} |
83 |
| - */ |
84 |
| -var myPow = function (x, n) { |
85 |
| - let r = 1; |
86 |
| - let tmp = x; |
87 |
| - let tag = 0; |
88 |
| - if (n < 0) { |
89 |
| - tag = 1; |
90 |
| - n = -n; |
| 101 | +```cpp |
| 102 | +class Solution { |
| 103 | +public: |
| 104 | + double myPow(double x, int n) { |
| 105 | + long long N = n; |
| 106 | + return N >= 0 ? qmi(x, N) : 1.0 / qmi(x, -N); |
91 | 107 | }
|
92 |
| - while (n) { |
93 |
| - if (n & 1) { |
94 |
| - r *= tmp; |
| 108 | + |
| 109 | + double qmi(double a, long long k) { |
| 110 | + double res = 1; |
| 111 | + while (k) { |
| 112 | + if (k & 1) { |
| 113 | + res *= a; |
| 114 | + } |
| 115 | + a *= a; |
| 116 | + k >>= 1; |
95 | 117 | }
|
96 |
| - tmp *= tmp; |
97 |
| - n >>>= 1; |
| 118 | + return res; |
98 | 119 | }
|
99 |
| - return tag ? 1 / r : r; |
100 | 120 | };
|
101 | 121 | ```
|
102 | 122 |
|
103 | 123 | ### **Go**
|
104 | 124 |
|
105 | 125 | ```go
|
106 | 126 | func myPow(x float64, n int) float64 {
|
107 |
| - p := abs(n) |
108 |
| - res := 1.0 |
109 |
| - for p != 0 { |
110 |
| - if p&1 == 1 { |
111 |
| - res *= x |
112 |
| - } |
113 |
| - x *= x |
114 |
| - p = p >>1 |
115 |
| - } |
116 |
| - if n < 0 { |
117 |
| - return 1/res |
118 |
| - } |
119 |
| - return res |
| 127 | + if n >= 0 { |
| 128 | + return qmi(x, n) |
| 129 | + } |
| 130 | + return 1.0 / qmi(x, -n) |
120 | 131 | }
|
121 | 132 |
|
122 |
| -func abs(x int) int { |
123 |
| - if x > 0 { |
124 |
| - return x |
125 |
| - } |
126 |
| - return -x |
| 133 | +func qmi(a float64, k int) float64 { |
| 134 | + var res float64 = 1 |
| 135 | + for k != 0 { |
| 136 | + if k&1 == 1 { |
| 137 | + res *= a |
| 138 | + } |
| 139 | + a *= a |
| 140 | + k >>= 1 |
| 141 | + } |
| 142 | + return res |
127 | 143 | }
|
128 |
| - |
129 | 144 | ```
|
130 | 145 |
|
131 |
| -### **C++** |
| 146 | +### **JavaScript** |
132 | 147 |
|
133 |
| -```cpp |
134 |
| -class Solution { |
135 |
| -public: |
136 |
| - double myPow(double x, int n) { |
137 |
| - long m = n; |
138 |
| - if (m < 0) { |
139 |
| - x = 1 / x; |
140 |
| - m = -m; |
| 148 | +```js |
| 149 | +/** |
| 150 | + * @param {number} x |
| 151 | + * @param {number} n |
| 152 | + * @return {number} |
| 153 | + */ |
| 154 | +var myPow = function (x, n) { |
| 155 | + return n >= 0 ? qmi(x, n) : 1 / qmi(x, -n); |
| 156 | +}; |
| 157 | + |
| 158 | +function qmi(a, k) { |
| 159 | + let res = 1; |
| 160 | + while (k) { |
| 161 | + if (k & 1) { |
| 162 | + res *= a; |
141 | 163 | }
|
142 |
| - double ans = 1; |
143 |
| - while (m) { |
144 |
| - if (m & 1) { |
145 |
| - ans *= x; |
146 |
| - } |
147 |
| - x *= x; |
148 |
| - m >>= 1; |
| 164 | + a *= a; |
| 165 | + k >>>= 1; |
| 166 | + } |
| 167 | + return res; |
| 168 | +} |
| 169 | +``` |
| 170 | + |
| 171 | +### **TypeScript** |
| 172 | + |
| 173 | +```ts |
| 174 | +function myPow(x: number, n: number): number { |
| 175 | + return n >= 0 ? qmi(x, n) : 1 / qmi(x, -n); |
| 176 | +} |
| 177 | + |
| 178 | +function qmi(a: number, k: number): number { |
| 179 | + let res = 1; |
| 180 | + while (k) { |
| 181 | + if (k & 1) { |
| 182 | + res *= a; |
149 | 183 | }
|
150 |
| - return ans; |
| 184 | + a *= a; |
| 185 | + k >>>= 1; |
151 | 186 | }
|
152 |
| -}; |
| 187 | + return res; |
| 188 | +} |
153 | 189 | ```
|
154 | 190 |
|
155 | 191 | ### **C#**
|
156 | 192 |
|
157 | 193 | ```cs
|
158 | 194 | public class Solution {
|
159 | 195 | public double MyPow(double x, int n) {
|
160 |
| - if (n == 0) { |
161 |
| - return 1; |
162 |
| - } |
163 |
| - if (n == 1) { |
164 |
| - return x; |
165 |
| - } |
166 |
| - if (n == -1) { |
167 |
| - return 1 / x; |
| 196 | + long N = n; |
| 197 | + return n >= 0 ? qmi(x, N) : 1.0 / qmi(x, -N); |
| 198 | + } |
| 199 | + |
| 200 | + private double qmi(double a, long k) { |
| 201 | + double res = 1; |
| 202 | + while (k != 0) { |
| 203 | + if ((k & 1) != 0) { |
| 204 | + res *= a; |
| 205 | + } |
| 206 | + a *= a; |
| 207 | + k >>= 1; |
168 | 208 | }
|
169 |
| - double half = MyPow(x, n / 2); |
170 |
| - return half * half * MyPow(x, n % 2); |
| 209 | + return res; |
171 | 210 | }
|
172 | 211 | }
|
173 | 212 | ```
|
|
0 commit comments