Conversation
| base = x | ||
| exponent = n | ||
| bit = 1 | ||
| result = 1 | ||
| while exponent >= bit: | ||
| if exponent & bit > 0: | ||
| result *= base | ||
| bit <<= 1 | ||
| base *= base |
There was a problem hiding this comment.
同じことですが、exponentに対し左シフトしていき、逐次1の位をみるという風にも書けますね。
base = x
exponent = n
result = 1
while exponent:
if exponent & 1:
result *= base
exponent >>= 1
base *= base変数bitを消せるので自分はこちらのが好みですね。
| else: | ||
| base = 1 / x |
There was a problem hiding this comment.
本問の入力制約ではありえないですが、xが0のとき、ここでZeroDivisionErrorとなってしまうので、想定した条件分岐を追加してみても良いかもしれません。
0^0 == 0 にすることが多いですが、どちらにしてもどちらから近づくかで極限が異なるので難しい問題をはらんでいます。
https://discord.com/channels/1084280443945353267/1262688866326941718/1351742235238076458
There was a problem hiding this comment.
あ、すみません。0^0 == 1 にすることのほうが多いと思います。(これは数学の話なので、あんまりプログラミングは関係ないですが。)
| while exponent != 0: | ||
| if exponent % 2 == 1: | ||
| result *= base | ||
| exponent -= 1 |
| while exponent != 0: | ||
| if exponent % 2 == 1: | ||
| result *= base | ||
| exponent -= 1 | ||
| base = base ** 2 | ||
| exponent //= 2 |
There was a problem hiding this comment.
divmodを使ってみることもできます。好みの範囲ですね。
while exponent:
exponent, least_significant_bit = divmod(exponent, 2)
if least_significant_bit:
result *= base
base = base ** 2| 呼び出しごとに深さが半分になるようにした。O(nlog(n))になる、これでもTLEするだろう。 | ||
| 再帰呼び出しの木を書いたら同じ計算をたくさん行ってることに気づいたのでキャッシュした。 | ||
| こうすると時間計算量はO(log(n))になる。 | ||
| ざっくり評価なので実行時間ちゃんと見積もれるようになりたい。 |
There was a problem hiding this comment.
実行時間の見積もり方については、以下のコメントが参考になるかもしれません。
Yuto729/LeetCode_arai60#16 (comment)
| # step1: 15分 | ||
| nがすごく大きい。 | ||
|
|
||
| 下記の実装だと再帰が深くなりすぎて落ちる。 |
There was a problem hiding this comment.
Python の再帰回数の上限については、以下をご参照ください。
https://docs.python.org/3/library/sys.html#sys.setrecursionlimit
https://docs.python.org/3/library/sys.html#sys.getrecursionlimit
参考までに自分の環境ではデフォルト値は 1000 でした。
LeetCode は、デフォルトで大きめの値に設定されていたと思います。
問題: 50. Pow(x, n)
次の問題: 779. K-th Symbol in Grammar