Skip to content

50. Pow(x, n)#45

Merged
garunitule merged 1 commit intomainfrom
50
Jan 8, 2026
Merged

50. Pow(x, n)#45
garunitule merged 1 commit intomainfrom
50

Conversation

@garunitule
Copy link
Owner

Comment on lines +103 to +111
base = x
exponent = n
bit = 1
result = 1
while exponent >= bit:
if exponent & bit > 0:
result *= base
bit <<= 1
base *= base

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同じことですが、exponentに対し左シフトしていき、逐次1の位をみるという風にも書けますね。

        base = x
        exponent = n
        result = 1
        while exponent:
            if exponent & 1:
                result *= base
            exponent >>= 1
            base *= base

変数bitを消せるので自分はこちらのが好みですね。

Comment on lines +58 to +59
else:
base = 1 / x

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

本問の入力制約ではありえないですが、xが0のとき、ここでZeroDivisionErrorとなってしまうので、想定した条件分岐を追加してみても良いかもしれません。

0^0 == 0 にすることが多いですが、どちらにしてもどちらから近づくかで極限が異なるので難しい問題をはらんでいます。

https://discord.com/channels/1084280443945353267/1262688866326941718/1351742235238076458

https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.d9ky6ipkmw98

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あ、すみません。0^0 == 1 にすることのほうが多いと思います。(これは数学の話なので、あんまりプログラミングは関係ないですが。)

while exponent != 0:
if exponent % 2 == 1:
result *= base
exponent -= 1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

下で切り捨て除算しているのでこの行は不要に見えます。

Comment on lines +80 to +85
while exponent != 0:
if exponent % 2 == 1:
result *= base
exponent -= 1
base = base ** 2
exponent //= 2

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

divmodを使ってみることもできます。好みの範囲ですね。

        while exponent:
            exponent, least_significant_bit = divmod(exponent, 2)
            if least_significant_bit:
                result *= base
            base = base ** 2

https://docs.python.org/3/library/functions.html#divmod

呼び出しごとに深さが半分になるようにした。O(nlog(n))になる、これでもTLEするだろう。
再帰呼び出しの木を書いたら同じ計算をたくさん行ってることに気づいたのでキャッシュした。
こうすると時間計算量はO(log(n))になる。
ざっくり評価なので実行時間ちゃんと見積もれるようになりたい。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

実行時間の見積もり方については、以下のコメントが参考になるかもしれません。
Yuto729/LeetCode_arai60#16 (comment)

# step1: 15分
nがすごく大きい。

下記の実装だと再帰が深くなりすぎて落ちる。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python の再帰回数の上限については、以下をご参照ください。
https://docs.python.org/3/library/sys.html#sys.setrecursionlimit
https://docs.python.org/3/library/sys.html#sys.getrecursionlimit

参考までに自分の環境ではデフォルト値は 1000 でした。

LeetCode は、デフォルトで大きめの値に設定されていたと思います。

@garunitule garunitule merged commit b721111 into main Jan 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants