かずとよのアウトプット日記

開発エンジニアを目指しています。

leetcode : Valid_Parentheses

こんにちは、かずとよです。

今回もleetcode。

まずは問題文が以下。

 

Given a string s containing just the characters '('')''{''}''[' and ']', determine if the input string is valid.

An input string is valid if:

  1. Open brackets must be closed by the same type of brackets.
  2. Open brackets must be closed in the correct order.

 

Example 1:

Input: s = "()"
Output: true

Example 2:

Input: s = "()[]{}"
Output: true

Example 3:

Input: s = "(]"
Output: false

Example 4:

Input: s = "([)]"
Output: false

Example 5:

Input: s = "{[]}"
Output: true

 

Constraints:

  • 1 <= s.length <= 104
  • s consists of parentheses only '()[]{}'.

 

簡単に解読すると

【与えられる文字列は、"(", ")", "{", "}", "[", "]" これら3種類の括弧のみ。

正しく使えているか判別しよう。】

ということみたい。

例1)"(" は ")" で閉じるのは、もちろんOK。

例3)"(" を "]" で閉じるのはダメ。

例4)最初と閉じとがおかしい。

みたいな感じですね。

 

 

ぶっちゃけ今回の問題、昨日から始めたのに、解けなさすぎて頭痛がやばくなって寝ました。

で、一旦コードから離れて、リフレッシュして、再挑戦!

 

・・・それでも解けなくて、他の人のコード見ました。

理解するまで読み込んで、勉強しました。

やっと理解できて自分でコード書けたので、アウトプット!

 

まずは、僕が最初書いてた、ダメダメコード↓↓

 

def is_valid(s)
    x = s.match(/(\((\]|\}))|(\[(\)|\}))|(\{(\)|\]))/)
    y = s.match(/\(\)|\[\]|\{\}/)
    z = s.match(/\)\(|\]\[|\}\{/)
    start_c = s.count("([{")
    end_c = s.count(")]}")
    if s.length == 1
      return false
    elsif x.to_s.length >= 2
      return false
    elsif y == nil
      return false
    elsif z.to_s.length >= 2
      return false
    elsif start_c == end_c
      return true
    end
end

 

ここまで、10回以上トライアンドエラーを繰り返してます。

ひとつクリアできても、次に出てくるテスト内容で引っかかるから、elseif増やして・・・みたいな感じで。

 

この後も、複数回これを繰り返しました。ほんとキリがないし、どんどんと見るに耐えないコードになっていってしまったので、挫折。

 

他の方があげてるコードを見て勉強し、自分なりに解釈して書いたコードが以下。

 

def is_valid(s)
  stack = []
  s.each_char do |c|
           # 渡された文字列を一文字ずつ繰り返し
    case c
           # cを以下の条件で振り分け
    when "(", "{", "["
           # 開始の括弧なら
      stack << c
           # cを配列へ。
#---------------------------------------①
    when ")"
           # )なら
      if stack.pop != "("
           # popメソッドで配列の最後を消しつつ、その要素が(じゃなければ
        return false
      end
#---------------------------------------①
#---------------------------------------①と同じ
    when "}"
      if stack.pop != "{"
        return false
      end
#---------------------------------------①と同じ
#---------------------------------------①と同じ
    when "]"
      if stack.pop != "["
        return false
      end
#---------------------------------------①と同じ
    end
  end
  return stack.empty?
           # 配列は空?→空ならtrue、何かあればfalse(空ということは、開始の括弧と閉じ括弧が同数)
end

 

まっっっったく違います。笑

 

 

まずは、最初僕が書いてたコードについて。

僕は何故か、正規表現を使いこなせば、コードを短く済ませる事ができるんじゃないか?と考えてしまいました。(正規表現使いこなせるのカッコイイから憧れてます)

その変なこだわりのせいで、目を酷使して、結果、頭痛くなったんだと思います。笑

正直、他の方のコードを参考にする数回前の失敗時点で、無理じゃね?って思ってたので、その段階で諦めて一旦まっさらの状態からスタートするべきだったかもしれません。

 

で、別の方のコードを参考にしたコード。

まず、popというメソッド。このコードの存在を知れた事がかなり大きかったです。

配列の最後の要素を消しつつその消した要素を扱えるとは・・・

今までの僕だと、stack[-1]で扱って、その後にdelete_atで消すとかしか発想がなかったので。

ほんと、知識は力だと思いました。

 

*今回の学び:

  • 書いていったコードがダメかもしれないなって思ったら、一旦捨ててみたほうが良いかもしれない。自分の最初の発想に囚われない。
  • 理解するためなら、他の方のコードは見た方がいい
  • popメソッドは、配列の最後の要素を消す。その際、消した要素を返す。
  • each_charでは、文字列を一文字ずつ繰り返し処理。
  • caseは、オブジェクトを指定し、後に書くwhenの条件にヒットしていたら、次のwhenかendまでの処理を実行する。

leet code : Longest_Common_Prefix

こんにちは。かずとよです。

本日も、leetcode解いていきます!

 

早速、問題文の原文が以下。

 

Write a function to find the longest common prefix string amongst an array of strings.

If there is no common prefix, return an empty string "".

 

Example 1:

Input: strs = ["flower","flow","flight"]
Output: "fl"

Example 2:

Input: strs = ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.

 

Constraints:

  • 0 <= strs.length <= 200
  • 0 <= strs[i].length <= 200
  • strs[i] consists of only lower-case English letters.

 

ここから、解読!

【文字列の配列の中から、最も長い共通のプレフィックスを見つけろ。

共通のプレフィックスがない場合は、空の文字列””を返しましょう。】

 

今回の問題は、割と翻訳したまんまでした。

でも、プレフィックスというのがよく分からん・・・

 

とりあえず、例文を見た感じ、共通の文字列を探し出すコードを書けばいいのかな?と。早速やってみました。

↑(これが、後の地獄の始まり)

 

かなりの試行錯誤の末・・・これで、どうだ!!(ここまでに5回以上の誤回答→熟考→修正を繰り返し、心折れかけ。)

def longest_common_prefix(strs)
  str_1 = strs[0]
           # 渡された配列の1つ目
  str_2 = strs[1]
           # 渡された配列の2つ目
  str_include = []
           # 同じ文字が何文字含まれるかを入れるための配列作っとく
  if str_2.include?(str_1.slice(0))
           # 配列の2つ目に配列の1つ目の1文字目が含まれていれば(例文:2のようなものをはじく)
    strs.each do |s|
           # 渡されてる配列を一つずつ繰り返し
      str_count = 0
      str_include_s = 0
      while s.to_s.include?(str_1.slice(0..str_count))
           # 要素に配列の1つ目の文字(頭〜繰り返し回数)が含まれているなら
        str_include_s += 1
        str_count += 1
        if str_count == s.length
           # 文字数文繰り返したら
          break
           # 強制的にループ終了
        end
      end
      str_include << str_include_s
    end
    return str_1.slice(0..str_include.min - 1)
  else
    return ""
  end
end

 

そして・・・

Runtime Error Message:

Line 7: undefined method `slice' for nil:NilClass (NoMethodError) in solution.rb (longest_common_prefix) Line 29 in solution.rb (__driver_helper__) Line 42 in solution.rb (block in _driver) Line 39 in solution.rb (each) Line 39 in solution.rb (each_slice) Line 39 in solution.rb (_driver) Line 54 in solution.rb (<main>)

Last executed input:

 

おっそろしくエラーでた。

7行目のsliceメソッドがおかしいよ?

なぜ?VSCodeでは問題なく出力できてるのに?

よく分からんけど、とりあえず、それ以外でできる方法考えるか・・・

ってことで、slice使わず、別の方法を試したりとか、めちゃくちゃ色々試しました。(10誤回答ぐらい。)

でも、一生クリアできない。なぜ?

 

 

・・・!!!!

Last executed input: ←これ、ちゃんと見てませんでした。激しく後悔。

inputがだったとき、このエラーでたよって言われてたんですね・・・

そりゃ、からっぽの配列の中身を操作できるわけないですよね。

でも、配列が空でも、その配列の中身を添字つけて指定して、変数定義(上のコードで2行目、3行目)は、エラーにならないんやなーと思いました。

 

まぁ、気持ちを切り替えて!そうと分かれば!

 

def longest_common_prefix(strs)
  if strs == []
           # 渡された配列が空なら
      return ""
           # 空の文字列を返す
  else
    str_1 = strs[0]
           # 渡された配列の1つ目
    str_include = []
           # 同じ文字が何文字含まれるかを入れるための配列作っとく
    strs.each do |s|
           # 渡されてる配列を一つずつ繰り返し
      str_count = 0
      str_include_s = 0
      while s.to_s.include?(str_1.slice(0..str_count))
           # 要素に配列の1つ目の文字(頭〜繰り返し回数)が含まれているなら
        str_include_s += 1
        str_count += 1
        if str_count == s.length
           # 文字数文繰り返したら
          break
           # 強制的にループ終了
        end
      end
      str_include << str_include_s
    end
    include_words = str_1.slice(0..str_include.min - 1)
           # 全ての要素に含まれる文字を変数定義
    if include_words == str_1
           # 全ての要素に含まれる文字が配列の1つ目と同じなら
      return ""
           # 空の文字列を返す(このコードを入れるまで、配列の要素が全て同じパターンはなかったので)
    else
      return include_words
    end
  end
end

どや!

 

Status: 

Time Limit Exceeded

Last executed input:

[""]

 

制限時間を超えました、だと?

 

あぁ、配列空っぽは空の文字列で返すようにしたけど、配列に空の文字列がある場合は指定してなかったな・・・

だから、whileで脱出できず、処理し続けちゃって、ちゃんとできてないんだな。

ここから、めちゃくちゃ試行錯誤。

そして、例文で把握しきれていなかったパターンが様々出てきて、その都度コードを修正しながら正解に近づく・・・

 

Input:["c","acc","ccc"]
Output:"c"
Expected:""
 
ある時出てきた、誤回答の為のこの内容。
cが全ての要素に含まれてるから合ってるやん!って、なりました。

 

これが、問題文のプレフィックスをちゃんと把握せずに進めた代償です。

僕は、全ての要素に共通して入っている文字だと思って、条件分岐にinclude?を使ってました。

でも、プレフィックスを調べたところ、【頭につく文字列】みたいな事らしく・・・。

 

発狂。

 

ここで、1から考え直しです。

大体の型は使いまわせるはずなので、熟考。

include?ではなく、indexを使うことにしました。

そしてまた、トライアンドエラーをひたすら繰り返し・・・

 

def longest_common_prefix(strs)
  strs_words = strs.join 
           # 渡された配列をひと繋ぎの文字列にする
  if strs.include?("") || strs_words.length == 0
           # 配列に空の文字列が含まれるか、ひと繋ぎにした文字数が0なら
      return ""
           # 空の文字列を返す
  else
    str_1 = strs[0]
           # 渡された配列の1つ目
    str_include = []
           # 同じ文字が何文字含まれるかを入れるための配列作っとく
    strs.each do |s|
           # 渡されてる配列を一つずつ繰り返し
      str_count = 0
      str_include_s = 0
      while s.index(str_1.slice(0..str_count)) == 0
           # 配列の1つ目の文字(頭〜繰り返し回数)が要素の頭にあるなら
        str_include_s += 1
        str_count += 1
        if str_count == s.length
           # 文字数文繰り返したら
          break
           # 強制的にループ終了
        end
      end
      str_include << str_include_s
    end
    include_words = str_1.slice(0..str_include.min - 1)
           # 全ての要素に含まれる文字を変数定義
    if strs.length == 1
           # 配列の中の要素が1つなら
      return include_words
           # 変数include_wordsを返す
    else
           # 配列の中の要素が複数なら
      if strs.all?{|w| w.index(include_words) == 0}
           # 配列の全ての要素の頭に変数include_wordsがあるなら
        return include_words
           # 変数include_wordsを返す
      else
        return ""
      end
    end
  end
end

 

これで、クリアできました。

ここまでで、35回の誤回答を叩き出しました・・・僕はアホかもしれません。

絶対もっといいコードあると思いますが、さすがに力尽きました。

 

*今回の学び:

  • 問題文はしっかり読み、分からないところは事前に調べる
  • プレフィックスとは、頭につく文字列のこと
  • all?メソッドは、配列の要素を繰り返し実行し、その後に書く{}の条件が全て真の場合にtrueを返すメソッド
  • indexメソッドは、文字列の中のどこに、指定の文字列が含まれているか返す
  • while文などの無限ループになる可能性があるものの中で、if文などでbleakとすることで、ループを脱出できる。
  • joinメソッドは、配列をひと繋ぎの文字列にできる。
    オプションがあり、それを使うと区切れたりする?

 

leetcode : Roman to Integer

こんにちは。かずとよです。

本日も、leetcodeです。

早速問題を。

Roman numerals are represented by seven different symbols: IVXLCD and M.

Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, 2 is written as II in Roman numeral, just two one's added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

  • I can be placed before V (5) and X (10) to make 4 and 9. 
  • X can be placed before L (50) and C (100) to make 40 and 90. 
  • C can be placed before D (500) and M (1000) to make 400 and 900.

Given a roman numeral, convert it to an integer.

 

Example 1:

Input: s = "III"
Output: 3

Example 2:

Input: s = "IV"
Output: 4

Example 3:

Input: s = "IX"
Output: 9

Example 4:

Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.

Example 5:

Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

 

Constraints:

  • 1 <= s.length <= 15
  • s contains only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M').
  • It is guaranteed that s is a valid roman numeral in the range [1, 3999].

 

めっちゃ長い。頑張って解読。

【ローマ数字では、I,V,X,L,C,D,Mの7つの異なる記号で数字を表します。I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000

(なんやかんや、この表し方の説明が続くので、省略)

ローマ数字を与えられたら、それを整数に変換してね】

みたいな感じだと思います。

長くなりそうだったので省略してしまいましたが、VI = 6とかIV = 4とかの説明や、それ以外のシンボルでも考え方は同じだよって書いてるみたいです。

 

まず、このシンボル。見たことあります。ファイナルファンタジーとかで。笑

でも、大体のは50以上になることないので、L以上のシンボルは初見でした。一つ学べました。

あと、このシンボルのIVとかVIの考え方も、今までなんとなくで理解してたところが理由込みで理解できたのでスッキリしました。

 

さて、色々学べて理解も進んだところで、早速解きます!!

 

試行錯誤します。かなり試行錯誤しました。

で、回答が以下。

 

def roman_to_int(s)
  s_ary = s.split(//)
           # とりあえず渡された値を分割して配列へ
  answer = 0
           # あとあとの回答のために変数定義

# -----------------------①

  s_ary.each_with_index do |s, idx|
           # 先ほど作った配列を繰り返し処理(インデックスも)
    if idx != 0
           # 配列の頭じゃなければ以下を処理
      if s == "V" && s_ary[idx - 1] == "I" || s == "X" && s_ary[idx - 1] == "I"
           # 要素がVで且つ、一つ前の要素がI。もしくは、要素がXで且つ、一つ前の要素がIなら
        s_ary[idx - 1] = "-I"
           # 一つ前の要素を-Iと置き換え
      elsif s == "L" && s_ary[idx - 1] == "X" || s == "C" && s_ary[idx - 1] == "X"
           # 要素がLで且つ、一つ前の要素がX。もしくは、要素がCで且つ、一つ前の要素がXなら
        s_ary[idx - 1] = "-X"
           # 一つ前の要素を-Xと置き換え
      elsif s == "D" && s_ary[idx - 1] == "C" || s == "M" && s_ary[idx - 1] == "C"
           # 要素がDで且つ、一つ前の要素がC。もしくは、要素がMで且つ、一つ前の要素がCなら
        s_ary[idx - 1] = "-C"
           # 一つ前の要素を-Cと置き換え
      end
    end
  end
# -----------------------①
# -----------------------② s_ary.each do |i| # 再度、配列の中身を繰り返し if i == "-I" # もし要素が-Iなら answer -= 1 # 答えから-1 elsif i == "-X" # もし要素が-Xなら answer -= 10 # 答えから-10 elsif i == "-C" # もし要素が-Cなら answer -= 100 # 答えから-100 else # それ以外(要素が-のないものなら) i.sub!(/I/, "1") i.sub!(/V/, "5") i.sub!(/X/, "10") i.sub!(/L/, "50") i.sub!(/C/, "100") i.sub!(/D/, "500") i.sub!(/M/, "1000") # 要素を数字(文字列で)に置き換え answer += i.to_i # 答えに先程の要素を数値に変換して足す end end

# -----------------------②
return answer end

 

一応これでクリアにはなりましたが・・・めちゃ長い。

この回答が、僕の持ってる知識と、調べられる限界でした。

 

あまりにも長くなったので、自分のために解説しておきます。

 

とりあえず、渡されたシンボルは一つずつ分割して配列に入れました。

それで、①について。

①では、この配列の中から、4や9、40や90などといった、マイナスの処理をしないといけないものを探し出して、マイナスとわかる形に置き換えました。

これ、最初は2個目のif文だけでやってました。

ただそうすると、頭にVやXなどがあった時、インデックスが-1になってしまって、配列の最後を見てしまい、意図しないところが置き換えられてしまうという事が起きたため、1個目のif文で囲みました。

 

次に②。②では、①で置き換えた配列の要素たちを合計するだけ。

ただ、配列の中身はまだシンボルのままだし文字列だし、文字列から数値に変換するとマイナスが消えちゃうし・・・っていうことで、if文で分岐させながら、答えとなる変数に足したり引いたりしていきました。

 

うーん・・・一応クリアできたものの、こんなんでいいのか?

ほんまにむずかしいです。

 

*今回の学び:

  • romanは、浪漫のことじゃない。笑
  • V、Xの次にもシンボルがあったという事。実生活では使わないので知らなかった。
  • VやXの前にあるIはマイナス。後にあるのはプラス。L、C、D、M等でも同じ考え方。
  • splitメソッドで、文字列を分割して配列に格納できる。引数に区切る文字などを入れて使うと、任意の場所で分割できる。今回は、//を引数とし、一文字ずつ分割して使った。
  • with_indexめちゃ便利
  • subメソッドでは、文字列の中の指定した部分を置き換えできる。
    今回は、置き換えた後に使いたかったので、元となるオブジェクト自体を変更できる破壊的メソッドsub!を使いました。

leetcode : Palindrome Number

こんにちは。かずとよです。

今回は、Palindrome Numberという問題を解きました。

問題は以下。

 

Given an integer x, return true if x is palindrome integer.

An integer is a palindrome when it reads the same backward as forward. For example, 121 is palindrome while 123 is not.

 

Example 1:

Input: x = 121
Output: true

Example 2:

Input: x = -121
Output: false
Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.

Example 3:

Input: x = 10
Output: false
Explanation: Reads 01 from right to left. Therefore it is not a palindrome.

Example 4:

Input: x = -101
Output: false

 

Constraints:

  • -231 <= x <= 231 - 1

 

翻訳+自分なりの解釈は以下。

【整数xが回文整数なら、true。違うならfalseと返す。

回文整数とは、前からでも後ろからでも同じ数値になる整数のこと。

121は回文整数で、123はそうではない。】

さらに例文2の文章

【このパターンは、前から読むと-121。後ろから読むと121-となる。

よって、回文整数ではない。】

 

ふむ・・・なるほど。

ということは、負の数は全て回文整数ではないということ。

ならば、これでどうじゃい!!

 

def is_palindrome(x)
    if x >= 0
           # xが0以上なら(正の数、もしくは0)
      x_reverse_s = x.to_s.reverse
           # 一旦xを文字列にして、反転。
      x_reverse = x_reverse_s.to_i
           # 数値に変換

      if x == x_reverse
           # ここで再度条件分岐。xと反転したもの(x_reverse)が同じなら
        return true
      else
        return false
      end

    else
           # そもそも負の数なら
      return false
    end
end


クリアできました。

今回は、意外とあっさりいけました。

知ってることだけで解けたので、web検索もなしでした。翻訳以外。

(そもそもfalseと返す記述をしてなかったり、0をfalseで返してしまったりといったミスはありましたが)

 

*今回の学び:

  • 回文整数とは、前から読んでも後ろから読んでも同じ数字になるもの。負の数は-がある時点で回文整数になり得ない。
  • 0も回文整数である。

 

leetcode : reverse integer

こんにちは。かずとよです。

今回は、reverse integerという問題のアウトプットです。

例の如く、英語の問題文が以下。

 

Given a signed 32-bit integer x, return x with its digits reversed. If reversing x causes the value to go outside the signed 32-bit integer range [-231, 231 - 1], then return 0.

Assume the environment does not allow you to store 64-bit integers (signed or unsigned).

 

Example 1:

Input: x = 123
Output: 321

Example 2:

Input: x = -123
Output: -321

Example 3:

Input: x = 120
Output: 21

Example 4:

Input: x = 0
Output: 0

 

Constraints:

  • -231 <= x <= 231 - 1

 

 

もちろん分からないので、翻訳しつつ解釈。

【xに渡した数字を反転させる。123なら、321というように。

ただし、xが32ビット整数の範囲を超えていた場合、0と出力させる。】

こんな感じだと思います。

・・・32ビット整数?なんじゃそりゃ?

まぁ、よくわからんけどとりあえずやってみよう。

以下、とりあえず試行錯誤した結果

 

# @param {Integer} x
# @return {Integer}
def reverse(x)
  if x >= 1
           # xが1以上なら(正の数なら)
      x_s = x.to_s.reverse
           # 一旦ひっくり返せる様に文字列に変換して、reverse
      return x_s.to_i
           # 数値に戻して返す
  elsif x <= -1
           # xが-1以下なら(負の数なら)
      x_s = x.to_s.reverse
           # ここは正の数字と同じ
      answer = (x_s.to_i) - (x_s.to_i * 2)
           # 上の反転処理の時に-が消えてしまったので、再度負の数にして、変数に代入
      return answer
  else
           #  残るは0だけなので
      return 0
  end
end

しかし、これでは不正解でした。

 

Input:1534236469
Output:9646324351
Expected:0

 

どうも、0を求めてるらしい。反転できてるのに・・・なんでだ?

考えてると、頭の隅っこで32ビット整数が存在をアピールしてきました。

やっぱり、32ビット整数をしっかり考えないといけないのかな・・・

 

ということで、調べました。

32ビットに格納できる符号なし整数の範囲は、0 から 4,294,967,295 である。

符号付き整数は −2,147,483,648 から 2,147,483,647 を格納できる。

とのことでした。

今回の例文をみていると、例文2に-123は-321とあります。

なので、今回意識しないといけないのは、さっき調べたものの符号付き整数の方。

 

確かに、不正解の時のoutputをみると、2,147,483,647を超えています。

なるほど、そうなるときは、0と返さないといけないのか・・・

 

 

そして、再度試行錯誤の末・・・

 

# @param {Integer} x
# @return {Integer}

def reverse(x)
  if x >= 1
           # xが1以上なら(正の数なら)
      x_s = x.to_s.reverse
           # 一旦ひっくり返せる様に文字列に変換して、reverse
      x_plus = x_s.to_i
           # 数値に戻す

      if x_plus >= 2147483648
           # ここで再度条件分岐。さっき定義した変数が32ビット整数以上なら
          return 0
      else
          return x_plus
      end

  elsif x <= -1
           # xが-1以下なら(負の数なら)
      x_s = x.to_s.reverse
           # ここは正の数字と同じ
      x_minus = (x_s.to_i) - (x_s.to_i * 2)
           # 上の反転処理の時に-が消えてしまったので、再度負の数に。

      if x_minus <= -2147483648
           # x_minusが32ビット整数の範囲を超えていたらという条件で。
          return 0
      else
          return x_minus
      end

  else
           #  残るは0だけなので
      return 0
  end
end

 

これで、なんとかクリアでした。

いやいや、マジで難しすぎるよ、これ。

現役エンジニアの方々は、こんなの余裕で解けるの?やばくね?って感じました。

 

*今回の学び:

  • .reverseで【文字列】を反転させる事ができる。(数値は不可)
  • 文字列へ変換すると、-は消え去る
  • 32ビット整数とは、32ビットに格納できる整数の範囲のこと。
    そもそも、2進数で表現されるので、32ビットに格納できる整数の範囲は、0〜2の32乗-1となる。
    16ビットは16乗、8ビットは8乗という様な感じらしい。
  • よって、32ビット整数とは、符号なしの場合、0から4,294,967,295。
    符号付き整数は、 −2,147,483,648 から 2,147,483,647。

leetcodeを始めました。

スキルテストで、leetcodeから出題されることがわかった為、登録をして初めてみました。

SNSサインアップができたので、とりあえず済ませ、早速・・・

 

全部、英語。

英語です。正直全然わからないものの、なんとか問題ページに辿り着き、とりあえず一問解いてみようと、難易度easyのtwo sumという問題を選択。

そして問題文が以下。

 

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

 

Example 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Output: Because nums[0] + nums[1] == 9, we return [0, 1].

Example 2:

Input: nums = [3,2,4], target = 6
Output: [1,2]

Example 3:

Input: nums = [3,3], target = 6
Output: [0,1]

 

Constraints:

  • 2 <= nums.length <= 103
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • Only one valid answer exists.

 

 

うん、わからん。

 

翻訳サイトを駆使して、問題文を読み解きます。

 

・・・おそらくですが。

【仮引数numsには数値がいくつか入った配列を、targetには数値ひとつを、実引数として渡します。

numsの中のどことどこの数値を足せばtargetになるかを出力させる。

当てはまるのは1パターンですよ。】

的な意味かな?おそらく。

 

早速、試行錯誤しながら解いてみて、導き出せた僕の回答は以下。(1時間ぐらいかかった・・・)

 

# @param {Integer[]} nums
# @param {Integer} target
# @return {Integer[]}

def two_sum(nums, target)
  nums.each_with_index do |i, idx|
           # 配列numsを繰り返し処理。オプションでインデックスも取得する
    x = target - i
           # 変数xにtargetからiを引いて、あと数字がいくつ残るかを代入
    if nums.include?(x) && nums.index(x) != idx
           # 配列内にxがあって、且つ、xがidxと同じでないならば
      y = nums.index(i)
      z = nums.rindex(x)
      return [y, z]
    end
  end
end

 

これで一応クリアできた・・・

めちゃくちゃ難しかったです。

 

*今回の学び:

  • each_with_indexを使うと、繰り返し処理の際にその処理をしている要素の順番も取得できる。
  • 配列.index(要素)で、その要素の場所を頭から探し、最初に当てはまった場所の順番を取得できる
  • 配列.rindex(要素)は、上記の逆から探してくれる版。
  • 2つの数字の和を探すときは、差を見ればすぐに探し出せる。

初投稿!

初めまして。

開発エンジニアを目指しています、かずとよです。

 

学んだことを言語化してアウトプットをするためにブログを開設しました。

先輩方にコメントをいただければ、大変嬉しいです。

もちろん、同じ様にエンジニアを志す方からのコメントもめちゃくちゃ嬉しいです。

 

次回投稿から、しっかりとアウトプットしていきたいと思っています。

よろしくお願いします!