オットセイの経営日誌

データサイエンス系ベンチャーを経営してます。経営のこと、趣味のことつぶやきます。

LeetCode / Sqrt(x)

https://leetcode.com/problems/sqrtx/

Implement int sqrt(int x).

Compute and return the square root of x, where x is guaranteed to be a non-negative integer.

Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.

Example 1:
Input: 4
Output: 2

Example 2:
Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since the decimal part is truncated, 2 is returned.

どの言語にも用意されている平方根(ルート)を求める関数を実装してみなさい、という問題です。
もちろん、全ての値をIterativeに確認するのではない方法が求められます。

解答・解説

解法1

コーディング問題でちょいちょい出てくるバイナリサーチで解きます。以前の記事にも登場しました。
改めて説明を載せておくと、バイナリサーチは日本語で言えば二分探索となりますが、その名の通り検索対象を2つに分けて探索の効率を上げます。
具体的には、ソート済みの配列に対する検索を行うにあたり、 中央の値を見て、検索したい値との大小関係を用いて、検索したい値が中央の値の右にあるか、左にあるかを判断して、片側には存在しないことを確かめながら検索していく手法です。

今回は変数xに対して、その平方根sqrt(x)がxより小さい値の中でどれなのかを特定する問題なので、
0からxまでの整数のリストに対してバイナリサーチをかけます。

class Solution:
    def mySqrt(self, x: int) -> int:
        l, r = 0, x
        while l <= r:
            mid = l + (r-l)//2
            if mid*mid <= x < (mid+1)*(mid+1):
                return mid
            elif x < mid*mid:
                r = mid
            else:
                l = mid + 1

これまた繰り返しの注意点となりますが、l + (r-l)//2のところで(r+l)//2としていないのは、和がオーバーフローしてしまうのを回避するためですね。