👻

LeetCode 09-palindrome-number - golangでのruneおよび2つのインデックスループ

に公開

LeetCodeのEasy問題の中から「9. Palindrome Number」を取り上げ、いくつかの言語で解いてみました。

09-palindrome-number

https://leetcode.com/problems/palindrome-number

数値が回文(palindrome)かどうかを判定する

文字列にして解く方法

数値を文字列変換をしてしまうのが最も簡単かと思い、実装しました

ruby
rubyの場合は文字列変換したあとにreverseメソッドを呼び出して比較します

# @param {Integer} x
# @return {Boolean}
def is_palindrome(x)
    return false if x < 0
    x.to_s == x.to_s.reverse
end

python
pythonはスライスを使って文字列を逆順にしたコピーを作成して比較します

class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        if x < 0:
            return False

        s = str(x)
        return s == s[::-1]

typescript

typescriptはString型で文字列を逆順する関数がないため、配列にした後にreverseして結合して作成して比較します

function isPalindrome(x: number): boolean {
    if (x < 0){
        return false
    }

    const s = x.toString()
    return s === s.split('').reverse().join('')
};

golang

runeを利用します。以下、runeについて

    // 文字リテラル 'あ' は、rune型として扱われる
    a_rune := 'あ'

    // 10進数と16進数で出力
    fmt.Printf("文字 'あ' のコードポイント:\n")
    fmt.Printf("10進数: %d\n", a_rune)  // %d は10進数
    fmt.Printf("16進数: U+%x\n", a_rune) // %x は16進数
    fmt.Printf("文字列: %s\n", string(a_rune)) // %sは文字列
文字 'あ' のコードポイント:
10進数: 12354
16進数: U+3042
文字列: あ

2つのインデックスを使ったforループで文字列を反転させ、元の文字列と比較します。

  • スライスの両端から同時に要素を操作する
  • ループの回数がスライスの長さの半分で済む
func isPalindrome(x int) bool {
    if x < 0 {
        return false
    }

    s := strconv.Itoa(x) // strconv.Itoa(x): 数値を文字列に変換
    runes := []rune(s)

    for i,j :=0, len(runes)-1; i<j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }

    return s == string(runes) // string(runes): 数値をコードポイントとして文字に変換
}

golangでの別の解法として、2つのインデックスループで、文字列の両端から文字を比較します。回文の文字列を作成せずに、左右の文字が一致しない場合は回文でないと判定する。

func isPalindrome(x int) bool {
    if x < 0 {
        return false
    }

    s := strconv.Itoa(x) // strconv.Itoa(x): 数値を文字列に変換
    runes := []rune(s)

    for i,j :=0, len(runes)-1; i<j; i, j = i+1, j-1 {
        if runes[i] != runes[j]{
          return false
        }
    }

    return true
}

c++

class Solution {
public:
    bool isPalindrome(int x) {
        if (x<0){
            return false;
        }

        std::string s1 = std::to_string(x);
        std::string s2 = s1;

        std::reverse(s2.begin(),s2.end());

        return s1 == s2;
    }
};

ラップアップ

各言語で文字列変換した方式で解くことができた。
golangのruneおよび2つのインデックスを使ったforループが興味深かった。他の言語ではライブラリや組み込み機能が充実しており、特にRubyやPythonでは非常に簡潔に実装できました。
また、数値のまま解く方式のほうがデータ構造およびアルゴリズムの学習になりそうだが、LeetCodeでPremiumプランでないとSoluitonがみれないので未対応です。

学習した内容

  • golangでのrune
  • golangでの2つのインデックスを使ったforループ

Discussion